问题描述
我想编写一个可以与参数一起使用的函数,否则该参数可能直接出现在基于范围的循环中:
template <typename Iterable>
void sayIt(const Iterable& stuff) {
for (const auto& e : stuff) {
cout << e << endl;
}
}
这对于stl容器和其他类型可以正常使用,但不适用于括号括起来的初始化程序:
std::vector<std::string> baz(2,"sorry");
sayIt(baz); // okay
sayIt({"foo","bar"}); // not okay
解决方法
Braced-init-list没有类型,并且导致template argument deduction失败。
非推断上下文
在以下情况下,用于构成P的类型,模板和非类型值不参与模板自变量的推导,而是使用在其他地方推导或明确指定的模板自变量。如果仅在非推导上下文中使用模板参数并且未明确指定模板参数,则模板参数推导将失败。
- 参数P,其A是一个大括号初始化列表,但P不是std::initializer_list,对一个参数的引用(可能是cv限定的)或对数组的引用:
您可以将模板参数明确指定为std::initializer_list
来绕开推论,
sayIt<std::initializer_list<std::string>>({"foo","bar"});
或添加另一个重载std::initializer_list
。
template <typename T>
void sayIt(std::initializer_list<T> stuff) {
sayIt<decltype(stuff)>(stuff);
}