为什么以下不编译:
struct a
{
int i;
};
template <typename T>
class b
{
public:
T mItem;
template <typename... Arguments>
b(Arguments&&... args) : mItem(std::forward<Arguments>(args)...)
{
}
};
int _tmain(int argc, _TCHAR* argv[])
{
b<a>(1);
return 0;
}
错误C2664:&#39; a :: a(const a&amp;)&#39; :无法从&#39; int&#39;转换参数1 到&#39; const a&amp;&#39;
但是只需添加一个像这样的额外参数就可以编译:
struct a
{
int i;
};
template <typename T>
class b
{
public:
T mItem;
template <typename... Arguments>
// just random extra argument
b(int, Arguments&&... args) : mItem(std::forward<Arguments>(args)...)
{
}
};
int _tmain(int argc, _TCHAR* argv[])
{
b<a>(1);
return 0;
}
有没有比简单地为b的构造函数添加额外(无用)参数更简洁的方法?
答案 0 :(得分:5)
您正在尝试依赖聚合初始化,但您需要使用大括号而不是括号来使用它:
template <typename... Arguments>
b(Arguments&&... args) : mItem{std::forward<Arguments>(args)...}
{
}
大括号意味着您正在使用列表初始化而不是值/直接初始化。当T
是聚合类型时,前者解析为聚合初始化,但后两者不是。是的,C ++初始化规则很奇怪。
答案 1 :(得分:1)
在第一种情况下,您尝试调用
a(1)
你还没有。
在第二种情况下,1
使用int
参数,其余参数(即无)参数args
。因此,您调用
a()
没关系。
请注意,在后一种情况下,您传递给1
的{{1}}的值会丢失,并且不会像您预期的那样转发到b<a>::b
。
答案 2 :(得分:-1)
您正尝试使用int初始化A. A对int没有任何了解,A中没有构造函数可以做到这一点。当你提供一个额外的int参数时,你只是丢弃它而不是用空参数列表初始化A,调用默认构造函数。