Error creating templates

This is my code to check if a class has a begin member function or not:

 template<typename T> struct has_begin { struct dummy {typedef void const_iterator;}; typedef typename std::conditional< has_iterator<T>::yes, T, dummy>::type TType; typedef typename TType::const_iterator Iter; struct fallBack{ Iter begin() const ; Iter end() const;}; struct checker : T, fallBack {}; template <typename B, B> struct cht; template<typename C> static char check(cht< Iter (fallBack::*)() const, &C::begin>*); // problem is here template<typename C> static char (&check(...))[2]; public: enum {no = (sizeof(check<checker>(0))==sizeof(char)), yes=!no}; }; 

If I changed the second argument of cht to check(cht< Iter (fallBack::*)() const, &C::begin>*); to &checker::begin , this does not change the semantics of the code, since the cht argument of the second template is always checker because of this enum {no = (sizeof(check<checker>(0))==sizeof(char))

but changing the code leads to error , which:

 prog.cpp: In instantiation of 'has_begin<std::vector<int> >': prog.cpp:31:51: instantiated from here prog.cpp:23:38: error: reference to 'has_begin<std::vector<int> >::checker::begin' is ambiguous 

I want to know what is the reason for this behavior.

+7
source share
1 answer

from Wikipedia article on SFINAE - Substitution error is not an error:

[...] when creating a set of candidates for overload resolution, some (or all) candidates of this set may be the result of replacing the derived template arguments for template parameters. If an error occurs during substitution, the compiler removes the potential overload from the candidate installed instead of stopping with a compilation error [...]

In your published code, an ambiguity error occurs when creating the check function template with the parameter C == typename has_begin<T>::checker , and this substitution leads to an error, so the instance is simply removed from the overload set.

If you change your code, a similar ambiguity error occurs with &checker::begin . However, this time this is not the result of replacing the C parameter template for the check function template. Substitution of the template parameter T from struct has_begin not related to the SFINAE rule, since this template has already been successfully created.

+3
source

All Articles