首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >初始化程序列表的赋值

初始化程序列表的赋值
EN

Stack Overflow用户
提问于 2014-04-20 19:39:16
回答 3查看 3.1K关注 0票数 2

下面的代码是我问题的最小例子。我创建了一个包含固定大小数组的简单模板类,并重载赋值操作符以接受定义方法size()begin() (例如,initializer_lists)的任何类。我不明白为什么g++不能解决我打给这个接线员的电话(我用gcc 4.6):

代码语言:javascript
复制
***.cpp: In function ‘int main()’:
***.cpp:46:22: error: no match for ‘operator=’ in ‘a = {42, -1.0e+0, 3.14158999999999988261834005243144929409027099609375e+0}’
***.cpp:46:22: note: candidates are:
***.cpp:23:8: note: template<class U> A<T, N>::self& A::operator=(const U&) [with U = U, T = double, unsigned int N = 3u, A<T, N>::self = A<double, 3u>]
***.cpp:8:7: note: A<double, 3u>& A<double, 3u>::operator=(const A<double, 3u>&)
***.cpp:8:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initialiser list>’ to ‘const A<double, 3u>&’
***.cpp:8:7: note: A<double, 3u>& A<double, 3u>::operator=(A<double, 3u>&&)
***.cpp:8:7: note:   no known conversion for argument 1 from ‘<brace-enclosed initialiser list>’ to ‘A<double, 3u>&&’

第一个候选列表是正确的,但是没有关联的错误消息。以下是代码:

代码语言:javascript
复制
#include <iostream>
#include <algorithm>
#include <initializer_list>

// ------------------------------------------------------------------------

template <typename T, unsigned N>
class A
{
public:

    typedef A<T,N> self;

    // Default ctor
    A() {}

    // Copy ctor
    template <typename U>
    A( const U& other ) { operator=(other); }

    // Assignemnt
    template <typename U>
    self& operator= ( const U& other )
    {
        if ( other.size() == N )
            std::copy_n( other.begin(), N, m_data );
            return *this;
    }

    // Display contents
    void print() const
    {
        for ( unsigned i = 0; i < N; ++i )
            std::cout << m_data[i] << " ";
        std::cout << std::endl;
    }

private:
    T m_data[N];
};

// ------------------------------------------------------------------------

int main()
{
    A<double,3> a;
    a = {42,-1.0,3.14159};
    a.print();
}

有人知道为什么这可能是模棱两可的,或者我做错了什么吗?

注意:理想情况下,我甚至希望用一个A<double,3> a = {42,-1.0,3.14159};替换主程序的前两行,但我不确定如何做,我目前得到了以下错误:

代码语言:javascript
复制
***: In function ‘int main()’:
***:45:34: error: could not convert ‘{42, -1.0e+0, 3.14158999999999988261834005243144929409027099609375e+0}’ from ‘<brace-enclosed initialiser list>’ to ‘A<double, 3u>’
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-20 20:01:16

auto不同,在这种情况下,带括号的列表被推导为initializer_list,模板参数演绎则认为它是一个非推导的上下文,除非存在相应的initializer_list<T>类型的参数,在这种情况下,可以推导出T

从第14.8.2.1/1节temp.deduct.call (重点后加)

模板参数推断是通过比较每个函数模板参数类型(称为P)和调用的相应参数类型(称为A)来完成的,如下所述。如果从P中删除引用和cv-限定符给出了某些P0std::initializer_list<P0>,并且参数是一个初始化程序列表(8.5.4),则对初始化程序列表中的每个元素执行扣减,将P0作为函数模板参数类型,并将初始化器元素作为其参数。否则,初始化器列表参数将导致参数被视为非推导的上下文 (14.8.2.5)。

因此,您的operator=的参数不会被推断为initializer_list<double>。要使代码工作,您必须定义一个接受operator=参数的initializer_list

代码语言:javascript
复制
template <typename U>
self& operator= ( const std::initializer_list<T>& other )
{
    if ( other.size() == N )
        std::copy_n( other.begin(), N, m_data );
    return *this;
}
票数 2
EN

Stack Overflow用户

发布于 2014-04-20 19:57:39

大括号括起来的初始化程序列表不一定具有std::initializer_list<T>类型,因此需要指定赋值运算符模板需要一个std::initializer_list

代码语言:javascript
复制
  template <typename U>
  A& operator=(std::initializer_list<U> other )
  {
    if ( other.size() == N )
      std::copy_n( other.begin(), N, m_data );
    return *this;
  }

代码语言:javascript
复制
  A& operator=(std::initializer_list<double> other )
  {
    if ( other.size() == N )
      std::copy_n( other.begin(), N, m_data );
    return *this;
  }

我必须说,如果大小不匹配,那么一个赋值操作符就会悄然失败,这似乎不是一个好主意。

票数 2
EN

Stack Overflow用户

发布于 2014-04-20 19:44:32

我得说是这样的:

代码语言:javascript
复制
A<double,3> a;
a = {42,-1.0,3.14159};

您正在使用默认构造函数初始化a,然后尝试在已经初始化的对象上使用初始化程序列表--这会抱怨缺少适当的operator=重载。相反,试着:

代码语言:javascript
复制
A<double,3> a = {42,-1.0,3.14159};

编辑:

您还没有定义所需的构造函数:

代码语言:javascript
复制
template <typename T, unsigned N>
class A
{
public:
    A(std::initializer_list list) : m_data(list) {}

//...
}
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23186775

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档