【问题标题】:How to make is_arithmetic<myClass>::value to be true?如何使 is_arithmetic<myClass>::value 为真?
【发布时间】:2014-10-17 22:12:36
【问题描述】:

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

#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

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

如果我在创建类时可以给它一个满足 is_arithmetic 的类型,那就太好了,但这似乎可能会导致 type_traits 出现问题?

或者我需要创建一个新的测试来检查

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

还是类似的?

如果可能的话,我宁愿只调整我的类,而不是函数,但我很好奇解决方案。

【问题讨论】:

  • 你需要写你自己的特质。
  • @T.C.好吧,我也是这么想的。像is_like_number 这样创建一个新的struct 并通过模板规范声明foo 是这样简单吗?没关系,你在下面回答。谢谢

标签: c++ templates


【解决方案1】:

标准库类型特征,例如 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 {};

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

Demo.

【讨论】:

  • 虽然很酷(真的),但它在 Visual Studio 2013 上并没有失败... :( 有什么想法吗?
  • @xtofl VC++ 不支持表达式 SFINAE,这取决于它。
  • 尝试获取这些运营商的地址是否也有效,还是会遇到其他问题?我的猜测是,即使这确实有效,由于需要函数指针强制转换来克服歧义问题,这将是不太有利的选择。但我不确定这是否是唯一可能阻碍这种方法的因素。
【解决方案2】:

std::is_arithmetic&lt;T&gt;::value 仅定义为 true,如果 T 是 C++ 标准的算术类型,它是整数或浮点类型,而后者又是基本类型:

类型boolcharchar16_tchar32_twchar_t,以及有符号和无符号整数类型统称为整数类型

有三种浮点类型:floatdoublelong double

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-12
    • 1970-01-01
    • 2021-07-25
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    相关资源
    最近更新 更多