SFINAE无法有条件地编译成员函数模板 [英] SFINAE not working to conditionally compile member function template

查看:69
本文介绍了SFINAE无法有条件地编译成员函数模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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
}

但是由于某种原因,Visual c ++不断给我一个编译器错误,指出已经定义了 foo .即使很明显,根据类的模板参数,也只有一个函数的格式正确.因此SFINAE应该从考虑中删除第二个.

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?

推荐答案

尝试使用

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将启用/禁用模板类型参数的默认值;但是默认值不参与重载解析,因此,在您的情况下,您有两个功能

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.

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

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.

这篇关于SFINAE无法有条件地编译成员函数模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆