Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I template overload?

Why is it that this compiles:

class Testable {
public:
    template <bool flag>
    typename std::enable_if<flag>::type
    void foo() { cout << "Yay" << endl; }

    template <bool flag>
    typename std::enable_if<!flag>::type
    void foo() { cout << "Nay" << endl; }
};

But not if I define both foos using default types like so:

    template <bool flag, typename = typename std::enable_if<flag>::type>
    void foo() { cout << "Yay" << endl; } // (A)

    template <bool flag, typename = typename std::enable_if<!flag>::type>
    void foo() { cout << "Nay" << endl; } // (B)

I get this error (first line pointing to the definition of (B), second one pointing to (A)):

error: 'template<bool flag, class> void Testable::foo()' cannot be overloaded
error: with 'template<bool flag, class>> void Testable::foo()'
like image 515
Barry Avatar asked Apr 26 '13 17:04

Barry


1 Answers

The compiler complains because the two function templates have the same signature. Paragraph 1.3.18 of the C++11 Standard specifies what the signature of a function template is defined by:

<function template> name, parameter type list (8.3.5), enclosing namespace (if any), return type, and template parameter list

As you can see, default template arguments are not part of the signature.

You could work around this problem by changing your definition of Testable as follows:

class Testable {
public:
    template <bool flag, typename std::enable_if<flag>::type* = nullptr>
    void foo() { cout << "Yay" << endl; } // (A)

    template <bool flag, typename std::enable_if<!flag>::type* = nullptr>
    void foo() { cout << "Nay" << endl; } // (B)
};
like image 142
Andy Prowl Avatar answered Sep 19 '22 15:09

Andy Prowl