如何解决含std::initializer_list的dLinkedList构造函数冲突问题
解决dLinkedList构造函数的列表初始化歧义问题
问题根源
C++标准规定,当使用**花括号列表初始化({})**时,std::initializer_list类型的构造函数拥有最高匹配优先级。因此dLinkedList test1 {10, 108};会优先匹配接受std::initializer_list<int>的构造函数,而非你预期的(size_t, int)版本——即便10可以隐式转换为size_t。
解决方案
方案1:改用圆括号初始化(最简单直接)
放弃花括号语法,改用圆括号调用构造函数:
dLinkedList test1(10, 108);
圆括号初始化不会优先匹配std::initializer_list构造函数,编译器会正常匹配explicit dLinkedList(size_t, int)版本。
方案2:通过标签分派区分构造函数
如果希望保留花括号语法,可以给批量初始化的构造函数添加一个标签参数,彻底避免歧义:
- 在类外部或内部定义一个空标签结构体:
struct BatchInitTag {};
- 修改批量初始化构造函数的签名:
dLinkedList(BatchInitTag, size_t numberOfNode, int initializationValue) { createFirstNode(initializationValue); for(size_t i = 1; i < numberOfNode; ++i) push_back(initializationValue); nodeCount = new size_t; updateNodeCount(); }
- 调用时传入标签:
dLinkedList test1{BatchInitTag{}, 10, 108};
方案3:显式类型转换(临时应急)
在列表初始化时,显式将第一个参数转换为size_t,虽然可行但不够优雅:
dLinkedList test1{static_cast<size_t>(10), 108};
修正你的std::initializer_list构造函数
你的原initializer_list构造函数存在两个明显问题:
if(arg.size() == 0) dLinkedList(1);只是创建了一个临时对象,对当前对象的初始化毫无作用;- 循环从
arg.begin()+1开始,遗漏了初始化列表的第一个元素。
修正后的版本:
dLinkedList(const std::initializer_list<int> &arg) { if(arg.empty()) { createFirstNode(0); // 或你期望的默认值 } else { auto it = arg.begin(); createFirstNode(*it); ++it; for(; it != arg.end(); ++it) { push_back(*it); } } nodeCount = new size_t; updateNodeCount(); }
内容的提问来源于stack exchange,提问作者SogaBan
相关产品推荐
相关产品推荐

