2016-12-15 59 views
1

我有两套代码,其中第一个编译和行为与预期相同,但[看似是]不必要的冗长:具有类型特征的模板元编程:为什么第一个代码编译,第二个编译不?

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    template<point_type t2 = type> 
    point2d_base(std::enable_if_t<t2 == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    template<point_type t2 = type> 
    explicit point2d_base(std::enable_if_t<t2 != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

这是我宁愿写代码,但是我得到很多很多的编译错误,如果我不喜欢这样写道:

template<point_type type, typename T> 
struct point2d_base { 
    std::enable_if_t<std::is_arithmetic_v<T>, T> x, y; 
    point2d_base(std::enable_if_t<type == point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
    explicit point2d_base(std::enable_if_t<type != point_type::generic, T> x = 0, T y = 0) : 
     x(x), y(y) {} 
/*Some unrelated code*/ 
}; 

以供参考,point_type是一个“枚举类”包含三个值:genericcornercenter

我的问题是:为什么第一个代码编译,第二个没有?

回答

1

您不能依赖您的模板类参数来使用std::enable_if。 如果要将std::enable_if用作函数,则必须使该函数成为模板函数。 这是因为当你的类模板被实例化时,该类的所有成员函数也会实例化。您需要一个模板成员函数来有条件地启用或不启用该功能。 (这是我的猜测,我认为是正确的)

+0

是否有一个更接近我在第二个示例中编写的代码的正确版本,其中我不需要将'type'变量重新声明为别的东西? – Xirema

+0

如果你想使用'std :: enable_if',我不这么认为。基于您的要求的其他选项可以是模板专业化。 – MRB