使用enable_if对类方法进行部分模板专门化

Bas*_*scy 2 c++ templates

我有一个模板类,我想为其专门化整数类型的方法之一。我看到很多使用enable_if特征对模板化函数执行此操作的示例,但我似乎无法获得在类方法上执行此操作的正确语法。

\n

我究竟做错了什么?

\n
#include <iostream>\n\nusing namespace std;\n\ntemplate<typename T>\nclass Base {\n    public:\n    virtual ~Base() {};\n    \n    void f() {\n        cout << "base\\n";\n    };\n};\n\ntemplate<typename Q>\nvoid Base<std::enable_if<std::is_integral<Q>::value>::type>::f() {\n    cout << "integral\\n";\n}\n\ntemplate<typename Q>\nvoid Base<!std::enable_if<!std::is_integral<Q>::value>::type>::f() {\n    cout << "non-integral\\n";\n}\n\n\nint main()\n{\n    Base<int> i;\n    i.f();\n    \n    Base<std::string> s;\n    s.f();\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

上面的代码无法编译:

\n
main.cpp:16:60: error: type/value mismatch at argument 1 in template parameter list for \xe2\x80\x98template class Base\xe2\x80\x99\n   16 | void Base<std::enable_if<!std::is_integral<Q>::value>::type>::f() {\n      |                                                            ^\nmain.cpp:16:60: note:   expected a type, got \xe2\x80\x98std::enable_if<(! std::is_integral<_Tp>::value)>::type\xe2\x80\x99\nmain.cpp:21:61: error: type/value mismatch at argument 1 in template parameter list for \xe2\x80\x98template class Base\xe2\x80\x99\n   21 | void Base<!std::enable_if<!std::is_integral<Q>::value>::type>::f() {\n      |                                                             ^\nmain.cpp:21:61: note:   expected a type, got \xe2\x80\x98! std::enable_if<(! std::is_integral<_Tp>::value)>::type\xe2\x80\x99\nmain.cpp:21:6: error: redefinition of \xe2\x80\x98template void f()\xe2\x80\x99\n   21 | void Base<!std::enable_if<!std::is_integral<Q>::value>::type>::f() {\n      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nmain.cpp:16:6: note: \xe2\x80\x98template void f()\xe2\x80\x99 previously declared here\n   16 | void Base<std::enable_if<!std::is_integral<Q>::value>::type>::f() {\n      |      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n

Jar*_*d42 5

另一种选择是if constexpr(C++17):

template<typename T>
class Base
{
public:
    virtual ~Base() = default;
    
    void f() {
        if constexpr(std::is_integral<T>::value) {
            std::cout << "integral\n";
        } else {
            std::cout << "non-integral\n";
        }
    }
};
Run Code Online (Sandbox Code Playgroud)