如何使is_arithmetic <myclass> :: value为true?</myclass>

时间:2014-10-17 22:12:37

标签: c++ templates

我的想法是我有一个函数可以对输入做一些算术运算,所以可能是这样的:

#include <type_traits>
#include <vector>

using namespace std;

template<typename T> 
double mean(const vector<T>& vec)
{
    static_assert(is_arithmetic<T>::value, "Arithmetic not possible on this type");
    //compute mean (average)
}//mean

这很好用,并计算我输入的所有数字类型的平均值。但是我可以说我创建了一个新类:

class foo
{
    // class that has arithmetic operations created
};// foo

在这个类的定义中,我定义了所需的运算符+和/,因此它们可以处理预期的输入。现在我想在我的新类中使用我的mean函数,但由于static_assert,它显然不会编译。那么如何告诉编译器我的新类应该满足is_arithmetic<foo>::value

如果我在创建类时可以给它一个满足is_arithmetic的类型,那会很棒,但这看起来似乎会以某种方式导致type_traits出现问题?

或者我是否需要创建一个新的测试,检查以查看

is_arithmetic<T>::value || type(T,foo)

或类似的东西?

我宁愿只调整我的班级,而不是功能,如果可能的话,但我很想解决问题。

2 个答案:

答案 0 :(得分:19)

标准库类型特征,例如std::is_arithmetic,但有一个例外(std::common_type),&#34;设置为&#34;。尝试专门化它们会导致未定义的行为。 is_arithmetic测试类型是否是标准定义的算术类型;用户定义的类型绝不是算术类型。

您可以编写自己的特征来测试对算术运算符的支持:

template<class...> struct voidify { using type = void; };
template<class... Ts> using void_t = typename voidify<Ts...>::type;

template<class T, class = void>
struct supports_arithmetic_operations : std::false_type {};

template<class T>
struct supports_arithmetic_operations<T, 
           void_t<decltype(std::declval<T>() + std::declval<T>()),
                  decltype(std::declval<T>() - std::declval<T>()),
                  decltype(std::declval<T>() * std::declval<T>()),
                  decltype(std::declval<T>() / std::declval<T>())>> 
       : std::true_type {};

仅当所有四个表达式格式正确时(即T支持运算符+, -, *, /),部分特化才会匹配。

Demo

答案 1 :(得分:2)

根据定义,{p> std::is_arithmetic<T>::value只有true,如果T是C ++标准的算术类型,它是整数或浮点类型,而它只是基本类型:

  

类型boolcharchar16_tchar32_twchar_t以及有符号和无符号整数类型统称为整数类型< / em>的

     

有三种浮点类型:floatdoublelong double