SFINAE works differently in cases of type and non-type template parameters

后端 未结 5 474
遇见更好的自我
遇见更好的自我 2020-11-28 13:25

Why does this code work:

template<
    typename T, 
    std::enable_if_t::value, T>* = nullptr>
void Add(T) {}

templa         


        
5条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-28 14:09

    Here, the problem is that the template signature for add() is the same: A function template taking two parameters type.

    So when you write:

    template<
        typename T, 
        typename = std::enable_if_t::value, T>>
    void Add(T) {}
    

    That's fine, but when you write:

    template<
        typename T, 
        typename = std::enable_if_t::value, T>>
    void Add(T) {}
    

    You are redefining the first add() template, only this time you specify a different default type for the second template parameter: in the end, you defined an overload for add() with the exact same signature, hence the error.

    If you want to have several implementations like your question suggests, you should use std::enable_if_t as the return parameter of your template or use it in the same fashion as your first example. So your initial code becomes:

    template
    std::enable_if_t::value> Add(T) {}
    template
    std::enable_if_t::value> Add(T) {}
    

    Working example on Coliru

    On the code above, if T == int, the second signature becomes invalid and that triggers SFINAE.

    NB: Suppose you want N implementations. You can use the same trick as above but you'll need to make sure only one boolean among the N is true and the N-1 that remain are false, otherwise you'll get the exact same error!

提交回复
热议问题