为什么我的初始值设定项列表在类型推断中被半忽略?
Why is my initializer list semi-ignored for type deduction?
请考虑以下代码:
#include <unordered_map>
#include <iostream>
#include <vector>
template <typename Container, typename... Containers>
inline Container get_union(
const Container& c1,
const Containers&... more_containers)
{
Container result(c1);
auto f = [&result](const Container& c) {
result.insert(std::begin(c), std::end(c));
};
[](...){}(( f(more_containers), 0)...);
return result;
}
int main()
{
std::unordered_map<int, int> m1 = { {1, 2}, {3, 4} };
decltype(m1) m2 = get_union(m1, { {5, 6}, {7, 8} } );
std::cout << "m2.size() = " << m2.size() << "n'";
return 0;
}
当我尝试构建它时,我得到(coliru 链接):
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'int main()':
main.cpp:21:56: error: too many arguments to function 'Container get_union(const Container&, const Containers& ...) [with Container = std::unordered_map<int, int>; Containers = {}]'
decltype(m1) m2 = get_union(m1, { {5, 6}, {7, 8} } );
^
main.cpp:6:18: note: declared here
inline Container get_union(
^~~~~~~~~
如果编译器为容器类型选择空类型包,为什么这会导致错误?
引用cpp首选项上的列表初始化:
大括号的初始化列表不是表达式,因此没有类型,例如
decltype({1,2})
格式不正确。没有类型意味着模板类型推导无法推断出与大括号初始化列表匹配的类型,因此给定声明template<class T> void f(T);
表达式f({1,2,3})
格式不正确。
为什么编译器为容器类型选择空类型包
由于模板参数包可能模棱两可,有两种可能的方式可以解释(我认为)。由于两者都不是格式良好的,我不确定标准是否决定了哪种解释是正确的。
要么参数包的大小为 1,在这种情况下,将从格式错误的大括号初始化列表中推断出单个类型。
或者,由于在第一个参数之外没有传递任何类型,因此空参数包是
Containers
唯一可能的推导类型。现在,由于推导函数只接受单个参数,因此大括号的初始化列表太多了。这就是编译器选择解释的方式。
从根本上说,问题在于您正在尝试循环演绎。你显然试图从某种东西中推断出Containers
,如果它不是一个空包,那么这种东西的类型可以从任何Containers
中推断出来。
调用函数时无法从{}
推断。
template <typename Container, typename... Containers>
inline Container get_union(
Container c1,
std::initializer_list<Container> more_containers)
{
for (auto&& c:more_containers)
c1.insert( std::begin(c), std::end(c) );
return c1;
}
然后像这样调用:
auto m2 = get_union(m1, { { {5, 6}, {7, 8} } } );
现场示例
相关文章:
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 我的模板类方法返回错误类型?
- 如何为我的数组选择更大的数据类型?
- 如何判断类型双关语在我的平台上是否可以?
- 标准对此指向成员函数类型模板参数有何说明?是我的代码有误,还是 MSVS 16.6 有问题?
- 我的头文件 DNode 中的我的数据类型未被识别为数据类型
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 我的代码中是否有任何类型的错误,因为它没有给出正确的输出
- 为什么我的 for 循环给出错误:X 没有命名类型
- 是否允许调用方对我的 Builder 类使用任何指针类型(包括智能指针)?
- qsort 不适用于我的 impl 中的浮点类型。怎么了?
- turbo 为什么我的C++代码中出现错误类型名称预期"错误?
- 有没有办法根据 lambda 参数返回类型部分专用化我的模板化函数?
- 成员函数的"this"参数具有"const"类型,但我的函数实际上不是"const"
- 为什么C++数组索引值是有符号的,而不是围绕size_t类型构建的(或者我错了)
- 我的 SWIG 类型图有什么问题?
- 为什么我的函数不返回点类型?
- 为什么不调用预期的函数?我是否对类型特征的理解不正确?
- 无法将 int 类型转换为时间类型(我的类类型)