By Olumide


2015-06-20 11:05:17 8 Comments

#include <type_traits>

struct A{};
struct B{};

template <typename T>
struct Foo
{
    typename std::enable_if<std::is_same<T, A>::value>::type
    bar()
    {}

    typename std::enable_if<std::is_same<T, B>::value>::type
    bar()
    {}
};

Error message:

14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5: 
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()'

Source on cpp.sh. I thought both typename std::enable_if<std::is_same<T,?>::value>::type could not be valid at the same time.

Edit

For posterity here is my edit based on @KerrekSB's answer -- SFINAE only works for deduced template arguments

#include <type_traits>

struct A{};
struct B{};

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

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

int main()
{
};

1 comments

@Kerrek SB 2015-06-20 11:08:30

SFINAE only works for deduced template arguments, i.e. for function templates. In your case, both templates are unconditionally instantiated, and the instantiation fails.

The following variant works:

struct Foo
{
    template <typename T>
    typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {}

    // ... (further similar overloads) ...
};

Now Foo()(x) causes at most one of the overloads to be instantiated, since argument substitution fails in all the other ones.

If you want to stick with your original structure, use explicit class template specialization:

template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };

@Olumide 2015-06-20 11:15:21

SFINAE only works for deduced template arguments ... That's the key!!!!! Thanks bunch @Kerrek. BTW, my original post is MWE.

@Kerrek SB 2015-06-20 11:16:29

@Olumide: Yes, only substitution failures that result from deduction are not errors. Explicitly requested substitutions do fail as a hard error. (An MFE is enough for this case!)

@Brent 2017-06-01 22:52:16

Is there a way have an overloaded constructor like this?

Related Questions

Sponsored Content

26 Answered Questions

[SOLVED] Why do we need virtual functions in C++?

6 Answered Questions

27 Answered Questions

1 Answered Questions

17 Answered Questions

[SOLVED] Why can templates only be implemented in the header file?

5 Answered Questions

[SOLVED] Selecting a member function using different enable_if conditions

3 Answered Questions

1 Answered Questions

Compile error by using enable_if for SFINAE

3 Answered Questions

[SOLVED] How does this SFINAE C++ syntax work?

  • 2013-11-09 23:28:25
  • neuviemeporte
  • 1089 View
  • 3 Score
  • 3 Answer
  • Tags:   c++ templates sfinae

Sponsored Content