问题描述
这个想法是我有一个对输入进行算术运算的函数,所以可能是这样的:
The idea is that I have a function that does something arithmetic to the input, so maybe something like:
#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
这很好用,并计算我输入的所有数字类型的平均值.但是假设我创建了一个新类:
This works great, and computes the mean for all the number types that I put in. But lets say I then create a new class:
class foo
{
// class that has arithmetic operations created
};// foo
在这个类的定义中,我定义了所需的运算符 + 和/,因此它们可以处理预期的输入.现在我想在我的新类中使用我的平均函数,但由于 static_assert,它显然不会编译.那么我如何告诉编译器我的新类应该满足 is_arithmetic<foo>::value
?
And in the definition of this class, I defined the needed operators, + and /, so they work with expected inputs. Now I want to use my mean function with my new class, but it obviously won't compile due to the static_assert. So how do I tell the compiler that my new class should satisfy is_arithmetic<foo>::value
?
如果我在创建类时可以给它一个满足 is_arithmetic 的类型,那就太好了,但这似乎可能会以某种方式导致 type_traits 出现问题?
It would be great if when I create the class I could give it a type that satisfies is_arithmetic, but this seems like it might cause a problem with type_traits somehow?
或者我需要创建一个新的测试,检查以查看
Or would I need to create a new test, that checks to see
is_arithmetic<T>::value || type(T,foo)
或者类似的东西?
如果可能的话,我宁愿只调整我的类,而不是调整函数,但我很好奇解决方案.
I'd prefer to only have to adapt my class, rather than the function if possible, but I'm curious for a solution.
推荐答案
标准库类型特征,例如 std::is_arithmetic
,有一个例外(std::common_type
代码>),是一成不变的".尝试专门化它们会导致未定义的行为.is_arithmetic
测试类型是否为标准定义的算术类型;用户定义的类型绝不是算术类型.
The standard library type traits, such as std::is_arithmetic
, with one exception (std::common_type
), are "set in stone". Attempting to specialize them causes undefined behavior. is_arithmetic
tests if the type is an arithmetic type as defined by the standard; user-defined types are never arithmetic types.
您可以编写自己的特征来测试对算术运算符的支持:
You can write your own trait that tests for support for the arithmetic operators:
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
支持运算符 +、-、*、/
)时,部分特化才会匹配.
The partial specialization will match only if all four expressions are well-formed (i.e., that T
supports operators +, -, *, /
).
演示.
这篇关于如何使 is_arithmetic<myClass>::value 为真?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!