考虑以下示例:
#include <algorithm>
#include <iterator>
#include <vector>
template<class InputIterator, class T>
bool privIsElementOf(const T& element, InputIterator first, InputIterator last)
{
return ( std::find(first, last, element) != last );
}
template<class Container, class T>
bool isElementOf(const T& element, const Container & cont)
{
return privIsElementOf( element, std::begin(cont), std::end(cont) );
}
template<class T>
bool isElementOf(const T& element, const std::initializer_list<T> iList)
{
return privIsElementOf( element, std::begin(iList), std::end(iList));
}
int main()
{
std::vector<int> myVec { 1 , 3 , 5};
bool isElement = isElementOf(3, myVec);
bool isElement2 = isElementOf(3, {1 , 3, 5 });
return 0;
}
它与带有 initializer_list 的第二个 isElementOf 模板编译得很好。尽管如此,内容或多或少与第一个模板相同。它使用 std::begin 和 std::end。
当我删除第二个模板时,它显示以下编译错误:
initList.cpp: In function ‘int main()’: initList.cpp:31:47: error: no matching function for call to ‘isElementOf(int, )’ bool isElement2 = isElementOf(3, {1 , 3, 5 }); ^ initList.cpp:31:47: note: candidate is: initList.cpp:12:6: note: template bool isElementOf(const T&, const Container&) bool isElementOf(const T& element, const Container & cont) ^ initList.cpp:12:6: note: template argument deduction/substitution failed: initList.cpp:31:47: note: couldn't deduce template parameter ‘Container’ bool isElement2 = isElementOf(3, {1 , 3, 5 }); ^
谁能给我解释一下这个问题?该模板只是要求提供与 std::begin 和 std::end 兼容的类。为什么容器模板不适用于初始化列表?有没有办法只用一个模板解决问题?
最佳答案
A function parameter for which the associated argument is an initializer list (8.5.4) but the parameter does not have
std::initializer_list
or reference to possibly cv-qualifiedstd::initializer_list
type
是非推导上下文 (§14.8.2.5 [temp.deduct.type]/p5),因此编译器无法推导 Container
。 braced-init-list 本身没有类型。
一种可能性是提供一个默认模板参数来涵盖这种情况:
template<class T, class Container = std::initializer_list<T>>
bool isElementOf(const T& element, const Container & cont)
{
return privIsElementOf( element, std::begin(cont), std::end(cont) );
}
请注意,您不应使用 initializer_list
默认参数,除非您确定代码不会受到其复制语义的影响 - 底层数组的生命周期不受任何影响initializer_list
对象的复制。
关于c++ - 作为容器的初始化程序列表不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25738069/