下面的代码是我的问题的一个最小示例。我创建了一个包含固定大小数组的简单模板类,并重载了赋值运算符以接受定义方法 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 itA
) as described below. If removing references and cv-qualifiers fromP
givesstd::initializer_list<P0>
for someP0
and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, takingP0
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/