Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法在初始化中转换类型_C++_Templates_C++11_List Initialization - Fatal编程技术网

C++ 无法在初始化中转换类型

C++ 无法在初始化中转换类型,c++,templates,c++11,list-initialization,C++,Templates,C++11,List Initialization,我想我错过了什么,我不知道到底是什么。让我们看一下代码片段。 template <typename T> struct Foo { Foo (int n, int p, string s, T t = {}) : m_n {n}, m_p {p}, m_s {s}, m_t {t} {} const int m_n; const int m_p; const string m_s; T m_t; }; 使用方法: Foo&

我想我错过了什么,我不知道到底是什么。让我们看一下代码片段。
template <typename T>
struct Foo { 
    Foo (int n, int p, string s, T t = {})
    : m_n {n}, m_p {p}, m_s {s}, m_t {t}
    {}

    const int m_n;
    const int m_p;
    const string m_s;
    T m_t;
};
使用方法:

Foo<Boo> f_boo1 {1, 2, "A"};
Foo<Boo> f_boo2 {1, 2, "A", {1, 2}};
我可以创建如下Boo对象:

Foo<int> f_int1 {1, 2, "A", 155};
Foo<int> f_int2 {1, 2, "A"};
Boo boo1 {};
Boo boo2 {1, 2};
那么,你能告诉我问题出在哪里吗

可能的解决办法:

struct Boo {
    Boo () : z {}, l {} {}
    Boo (int p1, int p2) : z {p1}, l {p2} {}

    int z;
    int l;
};
以下两种说明均按预期工作:

Foo<Boo> f_boo1 {1, 2, "A"};
Foo<Boo> f_boo2 {1, 2, "A", {1, 2}};
foofu boo1{1,2,“A”};
Foo f_boo2{1,2,“A”{1,2};
对我来说,没关系,我看不出有什么理由不向类中添加两个构造函数,但是如果类型不是我的呢?我应该用构造函数编写简单的包装器吗

谢谢,
Artur

这是因为您试图在
Boo
上执行聚合初始化。见§8.5.4/3:

T
类型的对象或引用的列表初始化定义如下:

-如果
T
是聚合,则执行聚合初始化(8.5.1)

您打算复制您的
Boo
。。。但实际上,您正在进行聚合初始化,这会导致尝试从
Boo
构造
intz
,因此出现错误

错误:没有从“Boo”到“int”的可行转换

请注意,您可以在不使用任何模板的情况下用更少的代码重现问题:

Boo b;
Boo b2{b}; // error
解决办法很简单。只是不要使用列表初始化:

template <typename T>
struct Foo { 
    Foo (int n, int p, string s, T t = {})
    : m_n {n}, m_p {p}, m_s {s}, m_t(t)
    //                           ^^^^^^
{};
模板
结构Foo{
Foo(int n,int p,字符串s,T={})
:m_n{n},m_p{p},m_s{s},m_t(t)
//                           ^^^^^^
{};

同样的错误原因你能澄清一下为什么
{1,2}
被隐式转换为
Boo
而不是使用聚合初始化传递给ctor吗?难道
Foo
不是聚合吗?@vsoftco
Boo{1,2}
执行聚合初始化。
Boo{anything,at,all}
将是聚合初始化,因为
Boo
是聚合。@vsoftco
Foo
不是聚合,因为它有用户提供的构造函数。完整定义(8.5.1):聚合是一个数组或类,没有用户提供的构造函数,没有私有或受保护的非静态数据成员,没有基类,也没有虚拟函数。“这是标准中的一个缺陷,已通过@T.C.的分辨率修复。@T.C.很好!您知道如何跟踪编译器何时更新这类内容吗?clang 3.5.0和gcc 4.9.2,带-std=C++14,这两个版本仍然存在错误(以前是正确的吗?)。
Boo b;
Boo b2{b}; // error
template <typename T>
struct Foo { 
    Foo (int n, int p, string s, T t = {})
    : m_n {n}, m_p {p}, m_s {s}, m_t(t)
    //                           ^^^^^^
{};