C++;11-GCC/Clang中调用了错误的构造函数(不在VS 2013中)

C++;11-GCC/Clang中调用了错误的构造函数(不在VS 2013中),gcc,c++11,constructor,clang,Gcc,C++11,Constructor,Clang,我有这段代码,它在VS2013中运行良好,但在GCC4.8或Clang3.3中都没有编译 AND_end(c)->next = new ListNode<Point>{ b->val }; b是一行: using Line = ListNode<Point>*; 使用Line=ListNode*; ListNode是单链接列表的典型节点: template<typename T> struct ListNode { T val;

我有这段代码,它在VS2013中运行良好,但在GCC4.8或Clang3.3中都没有编译

    AND_end(c)->next = new ListNode<Point>{ b->val };
b是一行:

using Line = ListNode<Point>*;
使用Line=ListNode*;
ListNode是单链接列表的典型节点:

template<typename T>
struct ListNode
{
T val;              // Value
ListNode* next = nullptr;   // Next node in the list

// Constructor: takes a value of type T and optionally a pointer to the next node
explicit ListNode(T v, ListNode* n = nullptr)
    : val{ v }, next{ n }
{
    // Empty body, both member variables are initialized already
}
};
模板
结构列表节点
{
T val;//值
ListNode*next=nullptr;//列表中的下一个节点
//构造函数:获取一个类型为T的值,还可以选择一个指向下一个节点的指针
显式ListNode(tV,ListNode*n=nullptr)
:val{v},下一个{n}
{
//正文为空,两个成员变量都已初始化
}
};
因此,不编译的代码行应该执行以下操作:通过向显式ListNode构造函数提供其第一个(也是唯一一个)参数tV(即点)(b->val是点),创建一个新的ListNode,t=Point。此参数将使用默认的复制构造函数逐副本复制到ListNode成员val中。 在GCC和clang中似乎都发生了这样的情况:b->val被提供给了点构造函数,因此出现了上面的错误消息(并且为了完整性,还提供了额外的警告:“缺少字段'y'初始值设定项”)。 VC++12似乎完全正确


怎么了?我是否遗漏了任何明显的东西(可能不时发生),或者这里是否存在严重的问题?

我认为问题在于,您没有复制构造函数,因此,在这一行

显式ListNode(tV,ListNode*n=nullptr) :val{v},下一个{n}

由于没有复制构造函数,val{v}将尝试通过聚合进行初始化

从8.5.1开始

聚合是没有提供用户的数组或类(第9条) 构造器

当聚合由初始值设定项列表初始化时, 如8.5.4所述,采用初始值设定项列表中的元素 作为集合成员的初始值设定者,在 下标或成员顺序。每个成员都是从 相应的初始值设定项子句

对于点类型,聚合初始化应为val{v.x,v.y}

或者,您可以为Point类实现一个复制构造函数


GCC和Clang是正确的。VS是错误的,它应该拒绝您的代码。

我们看不到
行的定义,也看不到对象
b
实际上是什么。你能把它减少到a吗?使用
pow
到平方数。。。真正地使用乘法实现。仅供参考,这里有一个复制器:--您可以通过使用()而不是{}进行成员初始化来修复它。嗯,我可以看到:Line是ListNode*的typedef。无论如何,我可以发布一个简短的例子,100行。更好地使用pastebin或100行仍然可以在此处复制粘贴?失败的原因是聚合的列表初始化比复制构造更倾向于聚合初始化。在最新的C++1y草稿中似乎仍然是这样。默认和复制构造函数总是由编译器合成…除非删除,所以我认为这不是重点,我无法通过手动添加复制构造函数来解决问题。不过我会试试。。。
template<typename T>
struct ListNode
{
T val;              // Value
ListNode* next = nullptr;   // Next node in the list

// Constructor: takes a value of type T and optionally a pointer to the next node
explicit ListNode(T v, ListNode* n = nullptr)
    : val{ v }, next{ n }
{
    // Empty body, both member variables are initialized already
}
};