M.M*_*M.M 7 c++ aggregate perfect-forwarding c++14
#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
}
Run Code Online (Sandbox Code Playgroud)
最后一行给出错误: 17 : error: invalid conversion from 'const char*' to 'char' [-fpermissive]
如果我使用std::forward(args)...而不是args...那么更多的错误出现; 如果我尝试使用{'a', 'b', 'c', '\0'}初始化程序而不是字符串文字,也会有错误.
有没有办法使这项工作,即允许X z{......};在大括号内的任何合法初始化器的内容x2被接受并实际上初始化x2?
这是一个从C++ 98继承了不稳定的设计问题:某些转换或初始化被语法局限于文字,特别是字符串文字作为字符数组初始化([dcl.init.string]/1)和整数常量为空指针常量([conv.ptr]/1).当然,这与"完美"转发并不顺畅.
对于空指针,通过引入来避免该问题nullptr,0即使在转发之后也可以使用它来代替并且工作正常.
在您的情况下,基本上有两个主要选择:
Exploit brace elision - X也是一个聚合:
struct X {
X2 x2;
} z{1, 2, "abc"}; // Ok
Run Code Online (Sandbox Code Playgroud)声明buf具有类类型,例如std::string,或者在您的情况下可能更适合某些静态大小的等效类型(限制为10).