重载调用是不明确的:一对内联映射作为构造函数参数
Overloaded call is ambiguous: one-pair inline map as constructor argument
我有一个类——大致类似于下面的类——它将映射作为其唯一构造函数的唯一参数。
#include <iostream>
#include <map>
using namespace std;
class Dict {
public:
Dict (map<int, int> contents) {
elements = contents;
}
int getElement (int i) {
return elements[i];
}
map<int, int> elements;
};
int main() {
Dict* test0 = new Dict({{1, 2}, {3, 4}}); /* Succeeds */
Dict* test1 = new Dict({{1, 2}}); /* Fails */
}
如上面的注释中所述,第一个构造函数不会抛出错误;它与这样的答案一致。不明确的调用错误如下:
main.cpp:43:36: error: call of overloaded 'Dict()' is ambiguous
Dict* test1 = new Dict({{1, 2}}); /* Fails */
^
main.cpp:16:5: note: candidate: Dict::Dict(std::map)
Dict (map<int, int> contents) {
^
main.cpp:14:7: note: candidate: Dict::Dict(const Dict&)
class Dict {
^
main.cpp:14:7: note: candidate: Dict::Dict(Dict&&)
如果映射中的键和值是不同类型的(例如,如果Dict()
将整数映射到布尔值并且我调用new Dict({{1, true}})
(,则不会出现此错误,并且代码按预期工作。
这个单一的构造函数是如何模棱两可的?为什么在两个相同类型的对象之间有一个映射的情况下,它特别不明确?香草C++有什么明显的解决方法吗?
这主要是由std::map
的构造函数引起的:
template< class InputIterator >
map( InputIterator first, InputIterator last,
const Compare& comp = Compare(),
const Allocator& alloc = Allocator() );
即使参数不是迭代器,也会启用此构造函数,从而参与重载解析。结果,
{1, 2} -> std::map<int, int>
{{1, 2}} -> std::map<int, int>
都是有效的转化,这意味着
{{1, 2}} -> Dict
{{1, 2}} -> std::map<int, int>
都是有效的转换。因此,Dict
的三个构造函数是模棱两可的:
Dict(map<int, int>);
Dict(const Dict&);
Dict(Dict&&);
对于new Dict({{1, true}})
的情况,InputIterator
不能被正确地推导出来,因此不再有歧义。
您可以明确Dict(map<int, int>);
,或使用Ben Voigt建议的三对大括号。
为什么三副牙套可以工作?
因为在这种情况下,对于复制/移动构造函数候选项,不允许用户定义的转换。这在 [over.best.ics]/4 中明确说明(我不相关的部分被省略了(:
但是,如果目标是
构造函数的第一个参数或
。
并且构造函数或用户定义的转换函数是候选者
。或
[over.match.list] 的第二阶段,当初始值设定项列表只有一个元素本身就是初始值设定项列表,并且目标是类 X 构造函数的第一个参数,并且转换为 X 或引用 cv X,
不考虑用户定义的转换序列。
相关文章:
- 使用模板参数化映射旧版 C 接口的接口中的类型
- 具有不同参数列表的模板对象的模板静态映射
- 映射可变参数模板参数
- 重载调用是不明确的:一对内联映射作为构造函数参数
- lambda 和映射,引用参数 - 编译错误
- 具有单个参数的布尔函数映射
- 模板.参数包扩展 - 重映射类型
- C++函数来返回基于参数的比较器通用映射类型?
- 使用按插入方式排序的参数创建哈希映射
- C++ 使用映射中的参数调用函数
- 将模板类型参数的映射存储到C++中的矢量中:Visual Studio
- 如何使用成员函数映射参数包?(非恢复性,折叠前表达式)
- C 11多态映射键静态断言失败:哈希函数必须与密钥类型的参数无关
- 映射枚举值为C 中的模板参数
- 重映射模板参数结构
- 使用 C++11 可变参数模板初始化枚举到字符串映射
- OpenCV重映射参数以及如何使用它
- 带有映射参数的函数需要其他参数
- 函数指针作为映射参数时出错?C++
- 为boost::graph::copy_graph提供顶点映射参数