SFINAE not working to conditionally compile member function template

旧街凉风 提交于 2021-01-27 23:24:37

问题


I'm trying you use std::enable_if to conditionally choose only one out of two member function template using SFINAE with this code:

#include <iostream>
#include <type_traits>

template<typename T>
struct C {
    template<typename Q = T, typename = typename std::enable_if<std::is_same<Q, int>::value>::type>
    int foo() {
        return 1;
    }

    template<typename Q = T, typename = typename std::enable_if<!std::is_same<Q, int>::value>::type>
    int foo() {
        return 0;
    }

};

int main() {
    std::cout << C<int>().foo() << std::endl;  //error member function foo already defined
}

but for some reason, visual c++ keeps giving me a compiler error that foo is already defined. Even though, it is clear that, depending on the class' template argument, only one function is well-formed. So SFINAE should remove the second one from consideration.

Any idea why this does not work?


回答1:


Try with

template<typename T>
struct C {
    template<typename Q = T,
             typename std::enable_if<std::is_same<Q, int>::value, bool>::type = true>
    int foo() { // .............................................^^^^^^^^^^^^^^^^^^^^
        return 1;
    }

    template<typename Q = T, 
             typename std::enable_if<!std::is_same<Q, int>::value, bool>::type = true>
    int foo() { // ..............................................^^^^^^^^^^^^^^^^^^^^
        return 0;
    }

};

the point is that in your code SFINAE will enable/disable default values for template type parameter; but default values do not participate in overload resolution, so, in your case, you have two functions

template<typename, typename = void>
int foo() {
    return 1;
}

template<typename, typename>
int foo() {
    return 0;
}

with the same signature; so the compiler can't choose between the two and will give an error.

The code I proposed is different because in case the test of std::enable_if is false, you don't have the type (the element on the left of the =), not the value. Something as

// ................VVVVVV   what is = true ?
template<typename, = true>
int foo() {
    return 1;
}

that is a true "substitution failure" that disable the method.



来源:https://stackoverflow.com/questions/53806872/sfinae-not-working-to-conditionally-compile-member-function-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!