c++ - 初始化列表的分配

标签 c++ c++11 operator-overloading initializer-list overload-resolution

下面的代码是我的问题的一个最小示例。我创建了一个包含固定大小数组的简单模板类,并重载了赋值运算符以接受定义方法 size() 的任何类。和begin() (例如,initializer_list s)。我不明白为什么 g++ 无法解析我对此运算符的调用(我使用的是 gcc 4.6):

***.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>&&’

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

#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();
}

有谁知道为什么这可能不明确,或者我做错了什么?


注意:理想情况下,我什至想将 main 的前两行替换为 A<double,3> a = {42,-1.0,3.14159}; 。但我不知道如何,目前出现以下错误:

***: 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>’

最佳答案

auto不同,其中花括号初始化列表被推导为 initializer_list ,模板参数推导认为它是非推导上下文,除非存在类型为 initializer_list<T> 的对应参数。 ,在这种情况下 T可以推断。

来自§14.8.2.1/1 [temp.deduct.call](已添加强调)

Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below. If removing references and cv-qualifiers from P gives std::initializer_list<P0> for some P0 and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P0 as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.8.2.5).

这就是你的 operator= 的论点不会被推断为 initializer_list<double> 。为了使代码正常工作,您必须定义 operator=这需要 initializer_list论证。

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;
}

关于c++ - 初始化列表的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23186775/

相关文章:

c++ - 数组和普通指针与 std::unique_ptr 的区别

c++ - 静态局部变量被重新初始化

c++ - 如果在 map 中找不到键,则返回其他值

c++ - static const 成员是否有内部链接?

c++ - 如何找到正确的托管代理来构建 Linux 代码?

c++ - 类中重载 I/O 运算符的奇怪行为

c++ - 重载 "function call"运算符有什么用?

c++ - 是否可以根据另一个硬编码数组的数据自动生成硬编码数组?

c++ - 将字符串和整数散列在一起?

c++ - 定义适当的减法运算符