在函数定义中使用enable_if进行模板特化

M.k*_*ary 2 c++ templates template-specialization enable-if

如果我有以下功能

struct Struct { template<T> void Foo(); }
Run Code Online (Sandbox Code Playgroud)

如何enable_if在函数定义中使用而不重复上面的声明?

template<T> typename enable_if<is_class<T>,void>::type Struct::Foo() { ... } // error: Struct has no member `Foo<T>`
template<T> typename enable_if<!is_class<T>,void>::type Struct::Foo() { ... } // error: Struct has no member `Foo<T>`
Run Code Online (Sandbox Code Playgroud)

enable_if<is_class<T>,void>只是一个例子,但有没有办法不重复使用多个enable_if定义的声明?

看来我被迫这样做

struct Struct
{ 
   template<T> typename enable_if<is_class<T>,void>::type Foo();
   template<T> typename enable_if<!is_class<T>,void>::type Foo();
}
Run Code Online (Sandbox Code Playgroud)

Ted*_*gmo 6

不必过多重复的最简单方法是内联定义它们:

#include <type_traits>

struct Struct {
    template<class T>
    std::enable_if_t<std::is_class_v<T>> Foo() { /* ... */ }
    // same as:
    // std::enable_if_t<std::is_class_v<T>, void> Foo() { /* ... */ }    

    template<class T>
    std::enable_if_t<!std::is_class_v<T>> Foo() { /* ... */ }   
    // same as:
    // std::enable_if_t<!std::is_class_v<T>, void> Foo() { /* ... */ }
};
Run Code Online (Sandbox Code Playgroud)

或使用constexpr-if

struct Struct {
    template<class T>
    void Foo() {
        if constexpr (std::is_class_v<T>) {
            /* ... */
        } else {
            /* ... */
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这使得分离声明和定义稍微不那么冗长:

struct Struct {
    template<class T>
    void Foo() {
        if constexpr (std::is_class_v<T>) {
            /* ... */
        } else {
            /* ... */
        }
    }
};
Run Code Online (Sandbox Code Playgroud)