【问题标题】:SFINAE not working to conditionally compile member function templateSFINAE 无法有条件地编译成员函数模板
【发布时间】:2018-12-16 22:04:32
【问题描述】:

我正在尝试使用带有此代码的 SFINAE 使用 std::enable_if 有条件地仅从两个成员函数模板中选择一个:

#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
}

但由于某种原因,Visual C++ 不断给我一个编译器错误,foo 已经定义。尽管如此,很明显,根据类的模板参数,只有一个函数是格式良好的。所以 SFINAE 应该从考虑中删除第二个。

知道为什么这不起作用吗?

【问题讨论】:

    标签: c++ c++11 templates visual-c++ sfinae


    【解决方案1】:

    试试

    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;
        }
    
    };
    

    关键是在您的代码中,SFINAE 将启用/禁用模板类型参数的默认值;但默认值不参与重载决议,因此,在您的情况下,您有两个函数

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

    具有相同的签名;所以编译器无法在两者之间进行选择,会报错。

    我提出的代码不同,因为如果std::enable_if 的测试为假,则您没有类型(= 左侧的元素),而不是值。有点像

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

    这是禁用该方法的真正“替换失败”。

    【讨论】:

    • @GamefanA - 是的......我正在努力改善答案,但(对我来说)解释起来并不容易
    • @GamefanA - 答案改进;希望这更清楚。
    猜你喜欢
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多