Consider the following example:
#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; }
It compiles well with the second isElementOf template with the initializer_list parameter. However, the content more or less matches the content of the first template. It uses std :: begin and std :: end.
When I delete the second template, it shows the following compilation error:
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});
^
Can someone explain the problem to me? The template simply asks for a class that provides compatibility with std :: begin and std :: end. Why does the template for the container not work for the initialization list? Is there a way to solve the problem with only one template?
Living example