C++ 无法让SFINAE工作

C++ 无法让SFINAE工作,c++,c++11,template-meta-programming,sfinae,enable-if,C++,C++11,Template Meta Programming,Sfinae,Enable If,这是我第一次尝试SFINAE: #include <type_traits> #include <iostream> struct C1 { using T = int; }; struct C2 { using T = void; }; // For classes that declare T = int template <class C> void f(C &c, std::enable_if<!std

这是我第一次尝试SFINAE:

#include <type_traits>
#include <iostream>

struct C1 {
    using T = int;
};

struct C2 {
    using T = void;
};

// For classes that declare T = int
template <class C>
void f(C &c,
       std::enable_if<!std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "With T" << std::endl;
}

// For classes that declare T = void
template <class C>
void f(C &c,
       std::enable_if<std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "Without T" << std::endl;
}

int main() {
    C1 c1;
    f(c1); // With T
    C2 c2;
    f(c2); // Without T
    return 0;
}
#包括
#包括
结构C1{
使用T=int;
};
结构C2{
使用T=void;
};
//对于声明T=int的类
模板
f(C&C、,
std::enable_if::value,int>::type=0){

std::cout我做错了什么?

您需要几个
typename
才能工作:

// For classes that declare T = int
template <class C>
void f(C &c,
       typename std::enable_if<!std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "With T" << std::endl;
}

// For classes that declare T = void
template <class C>
void f(C &c,
       typename std::enable_if<std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "Without T" << std::endl;
}

你需要写
typename std::enable_if::type
,因为
type
是依赖的。如果你可以使用C++14,你可以使用
std::enable_if_t
,你就不会有这个问题。最好的办法是将
enable_if
s放在模板参数中,这样就不会使函数参数混乱。我对你的代码进行了编辑我想这些都是您刚才遗漏或键入错误的内容,但为了清楚起见,我添加了它们。此外,您没有使用
is\u void
is\u integral
有什么原因吗?根据您的用户名,我假设这些只是学习练习。:@erip根据我的用户名,我没有使用它们,因为我还没有学会它们:-)比谢谢你提到他们。
// For classes that declare T = int
template <class C>
void f(C &c,
       typename std::enable_if<!std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "With T" << std::endl;
}

// For classes that declare T = void
template <class C>
void f(C &c,
       typename std::enable_if<std::is_same<typename C::T, void>::value, int>::type = 0) {
    std::cout << "Without T" << std::endl;
}
// For classes that declare T = int
template <class C>
void f(C &c,
       std::enable_if_t<!std::is_same<typename C::T, void>::value, int> = 0) {
    std::cout << "With T" << std::endl;
}

// For classes that declare T = void
template <class C>
void f(C &c,
       std::enable_if_t<std::is_same<typename C::T, void>::value, int> = 0) {
    std::cout << "Without T" << std::endl;
}