c++ 专门用于is_arithmetic类型和特定类型的类模板

dxxyhpgq  于 2023-04-08  发布在  其他
关注(0)|答案(2)|浏览(177)

我想实现一个模板类,专门针对std::is_arithmetic类型,以及其他特定的vector类,例如:

struct Vector { double x = 0; double y = 0; double z = 0; };

我试过:

template<typename T, typename std::enable_if_t<std::is_arithmetic_v<T>>>
class arith { static constexpr const T zero() { return (T)0; } };

template<typename T, typename std::enable_if_t<std::is_same_v<typename T, Vector>>>
class arith { static inline Vector zero() { return Vector(); } };

这会导致“模板参数'__formal'与第二个模板上的声明不兼容
我尝试了一个泛型空类,它将被专门化:

template<typename T, typename Enable = void>
class arith { };

template<typename T, typename std::enable_if_t<std::is_arithmetic_v<T>>>
class arith { static constexpr const T zero() { return (T)0; } };

template<typename T, typename std::enable_if_t<std::is_same_v<typename T, Vector>>>
class arith { static inline Vector zero() { return Vector(); } };

但在这种情况下,两个专门化都无法编译,因为“模板参数'Enable'与声明不兼容”
我也尝试了Vector类的完全特殊化,以及其他各种解决方案......都没有成功。我可以通过对每种类型的完全特殊化来做到这一点,但无法让std::is_arithmetic版本工作。

irtuqstp

irtuqstp1#

这样做的正确语法如下所示。注意,当部分专用化一个类模板时,您没有使用***template-id***。

//------------------vvvv---->this is a non-type parameter
template<typename , auto >
class arith;

template<typename T, typename std::enable_if_t<std::is_arithmetic_v<T>> U>
//---------vvvvv------------------------------------------------------->note this 
class arith<T,U> { static constexpr const T zero() { return (T)0; } };

template<typename T, typename std::enable_if_t<std::is_same_v<T, Vector>> U>
//---------vvvvv------------------------------------------------------>note this
class arith<T,U> { static inline Vector zero() { return Vector(); } };

Working demo

y53ybaqx

y53ybaqx2#

在C++20之前,使用启用器的方式如下:

template<typename T, typename Enable = void>
class arith;

template<typename T>
class arith<T, std::enable_if_t<std::is_arithmetic_v<T>>>
{
    static constexpr const T zero() { return (T)0; }
};

// No need of SFINAE here: fully specialized
template<>
class arith<Vector> { static inline Vector zero() { return Vector(); } };

在C++20中,我们可以使用概念

template<typename T>
class arith;

template<typename T>
requires (std::is_arithmetic_v<T>)
class arith<T>
{
    static constexpr const T zero() { return (T)0; }
};

// No need of SFINAE here: fully specialized
template<>
class arith<Vector> { static inline Vector zero() { return Vector(); } };

Demo

相关问题