初始化列表作为容器不起作用

med*_*106 5 c++ templates c++11

考虑以下示例:

#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;
}
Run Code Online (Sandbox Code Playgroud)

它使用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兼容的类.为什么容器的模板不适用于初始化列表?有没有办法只用一个模板解决问题?

实例

T.C*_*.C. 6

一个函数参数,其关联参数是初始化列表(8.5.4),但该参数没有std::initializer_list或没有 引用可能的cv限定 std::initializer_list类型

是一个非推导的上下文(§14.8.2.5[temp.deduct.type]/p5),因此编译器无法推导出Container.一个支撑-初始化列表本身没有类型.

一种可能性是提供默认模板参数来涵盖这种情况:

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) );
}
Run Code Online (Sandbox Code Playgroud)

请注意,initializer_list除非您确定代码不会受其复制语义的影响,否则不应使用默认参数 - 基础数组的生命周期不受initializer_list对象复制的影响.