Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why sfinae overload is not resolved

This version works fine:

template<typename T>
struct Foo
{
    template<typename U = T>
        typename std::enable_if<std::is_same<U,A>::value>::type
        bar() { std::cout << "1" << std::endl; }

    template<typename U = T> 
        typename std::enable_if<std::is_same<U,B>::value>::type
        bar() { std::cout << "2" << std::endl; }
};  

This version fails:

template<typename T>
struct Foo2
{
    template<typename U = T, typename V = typename std::enable_if<std::is_same<U,A>::value>::type >
        V bar() { std::cout << "1" << std::endl; }

    template<typename U = T, typename V = typename std::enable_if<std::is_same<U,B>::value>::type >
        V bar() { std::cout << "2" << std::endl; }
};

with:

error: 'template template V Foo2::bar()' cannot be overloaded with 'template template V Foo2::bar()'

The difference between both versions is in the first I use the expression directly, in the second one I create a template default parameter and use that one as return type.

What is the reason to fail in the second example?

like image 802
Klaus Avatar asked Jun 06 '18 08:06

Klaus


1 Answers

Because in the case#2, the two bar are considered to be equivalent. When consider whether two function templates are equivalent or not, the default template parameters are ignored; they're not the part of function template signature. So they're considered as

template<typename U, typename V>
V bar() { std::cout << "1" << std::endl; }

template<typename U, typename V>
V bar() { std::cout << "2" << std::endl; }

As you can see, they're equivalent in fact.

(emphasis mine)

Two function templates are considered equivalent if

  • they are declared in the same scope
  • they have the same name
  • they have identical template parameter lists
  • the expressions involving template parameters in their return types and parameter lists are equivalent

The case#1 works because the return type is dependent on the template parameter and used with different expression; then they're considered not equivalent.

like image 105
songyuanyao Avatar answered Oct 11 '22 15:10

songyuanyao