无法使用 std::enable_if 在 g++/clang++ 上编译显式专用模板结构

Failing to compile explicitly specialized template struct on g++/clang++ with std::enable_if

我尝试用 msvc 编译它并且编译正常。另一方面,我没能用 g++ 和 clang++ 编译它。我得到的错误是 no type named ‘type’ in ‘struct std::enable_if<false, void>’。我该如何解决这个错误?

#include <type_traits>

template <bool v>
struct a {

    template <typename T = typename std::enable_if<v>::type>
    void function();

};

template struct a<false>;
template struct a<true>;

template<bool v>
template<typename T>
void a<v>::function() { }

int main() {

}

如果通过 bool 模板是 true,我正在尝试使 void function 可见。

您没有正确使用 SFINAE,因为您传递给 enable_if(即 v)的 bool 不依赖于函数模板参数。

有选择地添加或删除 class 模板成员的规范方法是使用模板专业化。例如:

template <bool v>
struct a {
    void function();
};

template< >
struct a<false> {
};

现在,只有 a<true> 会有 function 成员。如果您有许多共同成员应该出现在 a 中,而不管 v,您可以将这些成员移动到基础 class 并从中派生两个特化:

struct a_common {
    void common_function();
};

template <bool v>
struct a : public a_common {
    void function();
};

template< >
struct a<false> : public a_common {
};

这也可以通过 SFINAE 实现,但需要一些技巧。上面说了,我们需要把function做成模板,需要保证enable_if中使用的条件依赖于它的模板参数。由于我们没有任何模板参数,因此我们需要添加一个虚拟参数:

template <bool v>
struct a {
    template<
        typename Dummy = void,
        typename = typename std::enable_if<
            std::is_same< Dummy, Dummy >::value && v
        >::type
    >
    void function();
};

这里,我们在计算enable_if的第一个模板参数时,使用is_same trait引入对Dummy模板参数的形式依赖。自然地,is_same的结果将是true,因此v有效地决定了function模板是否可以被实例化。