数字类型的类模板

djW*_*ann 30 c++ templates

我怎样写只接受数字类型类模板(int,double,float等)作为模板?

chr*_*ris 43

您可以使用std::is_arithmetic类型特征.如果您只想启用具有此类型的类的实例化,请将其与std::enable_if以下内容结合使用:

#include <type_traits>

template<
    typename T, //real type
    typename = typename std::enable_if<std::is_arithmetic<T>::value, T>::type
> struct S{};

int main() {
   S<int> s; //compiles
   S<char*> s; //doesn't compile
}
Run Code Online (Sandbox Code Playgroud)

对于一个enable_if更容易使用的版本,以及免费添加disable_if,我强烈建议您阅读这篇精彩的文章(或缓存版本).

ps在C++中,上述技术的名称称为"替换失败不是错误"(大多数使用首字母缩略词SFINAE).您可以在维基百科cppreference.com上阅读有关此C++技术的更多信息.

  • 你可以不用`typename Dummy =`.此外,我强烈建议在这里使用[Wheels](https://bitbucket.org/martinhofernandes/wheels),它使代码变得更加简单:`template <typename T,wheels:EnableIf <wheels :: IsArithmetic <T >>>` (2认同)

Ben*_*Ben 16

我发现从该template<typename T, typename = ...>方法收到的错误消息高度神秘(VS 2015),但发现static_assert具有相同类型特征的a也有效,并允许我指定错误消息:

#include <type_traits>

template <typename NumericType>
struct S
{
    static_assert(std::is_arithmetic<NumericType>::value, "NumericType must be numeric");
};

template <typename NumericType>
NumericType add_one(NumericType n)
{
    static_assert(std::is_arithmetic<NumericType>::value, "NumericType must be numeric");
    return n + 1;
}

int main()
{
    S<int> i;
    S<char*> s; //doesn't compile

    add_one(1.f);
    add_one("hi there"); //doesn't compile
}
Run Code Online (Sandbox Code Playgroud)

  • 我同意“static_assert”更具可读性。缺点是它不参加SFINAE。这意味着您不能重载“addone”以获得仅接受非算术类型的版本。诚然,在这个例子中这并没有什么意义。然而,想象一下,您想要两个不同版本的“addone”。一种用于整数,一种用于浮点数。您无法使用“static_assert”来实现这一点。您需要使用“std::enable_if”。 (2认同)