无法使用 std::enable_if

时间:2021-01-17 15:26:46

标签: c++ typetraits 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() {

}

如果传递的 void function 模板为 bool,我正在尝试使 true 可见。

1 个答案:

答案 0 :(得分:4)

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

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

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

template< >
struct a<false> {
};

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

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

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

相关问题