#include <iostream>
struct X2
{
int i;
int j;
char buf[10];
};
X2 glob{1,2,"abc"}; // OK
struct X
{
X2 x2;
template<typename... Args>
X(Args&&... args): x2{args...} {}
};
int main()
{
X x; // OK
X y{1, 2}; // OK
X z{1, 2, "abc"}; // error
}
最后一行给出错误:17 : error: invalid conversion from 'const char*' to 'char' [-fpermissive]
如果我使用std::forward(args)...
代替args...
,则会出现更多错误;如果我尝试使用{'a', 'b', 'c', '\0'}
作为初始化程序而不是字符串文字,也会出错。
有没有办法让这项工作成功,即允许X z{......};
接受大括号内的任何内容作为x2
的合法初始值设定项,并且事实上初始化x2
?
答案 0 :(得分:5)
这是一个从C ++ 98继承的不稳定的设计问题:某些转换或初始化在语法上限于文字,特别是字符串文字作为char数组的初始值设定项([dcl.init.string] / 1)和整数文字作为空指针常量([conv.ptr] / 1)。当然,这与“完美”转发并不顺畅。
对于空指针,引入nullptr
可以避免问题,可以使用0
代替X
,并且即使在转发后也能正常工作。
在您的情况下,基本上有两个主要选项:
利用大括号 - struct X {
X2 x2;
} z{1, 2, "abc"}; // Ok
也是一个集合:
buf
声明std::string
具有类类型,例如let
或者,或许在您的情况下更合适一些静态大小的等效物(限于10号)。