我的想法是我有一个函数可以对输入做一些算术运算,所以可能是这样的:
#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
Run Code Online (Sandbox Code Playgroud)
这很好用,并且计算了我输入的所有数字类型的平均值.但是让我说我然后创建一个新类:
class foo
{
// class that has arithmetic operations created
};// foo
Run Code Online (Sandbox Code Playgroud)
在这个类的定义中,我定义了所需的运算符+和/,因此它们可以使用预期的输入.现在我想在我的新类中使用我的mean函数,但由于static_assert,它显然不会编译.那么如何告诉编译器我的新类应满足is_arithmetic<foo>::value
?
如果我在创建类时可以给它一个满足is_arithmetic的类型,那会很棒,但这似乎可能会导致type_traits出现问题?
或者我需要创建一个新的测试,检查看看
is_arithmetic<T>::value || type(T,foo)
Run Code Online (Sandbox Code Playgroud)
或类似的东西?
我更愿意只调整我的课程,而不是功能,如果可能的话,但我很想解决问题.
T.C*_*.C. 21
标准库类型特征,例如std::is_arithmetic
,有一个例外(std::common_type
),是"一成不变".尝试专门化它们会导致未定义的行为.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 {};
Run Code Online (Sandbox Code Playgroud)
只有当所有四个表达式格式正确(即T
支持运算符+, -, *, /
)时,部分特化才会匹配.
演示.