45

int数値型 ( 、doublefloatなど)のみをテンプレートとして受け入れるクラス テンプレートを作成するにはどうすればよいですか?

4

2 に答える 2

63

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
}

enable_ifの使いやすいバージョンと の無料追加については、この件に関する素晴らしい記事disable_ifを読むことを強くお勧めします。

C++ では、上記の手法には「置換の失敗はエラーではない」という名前があります (ほとんどの場合、頭字語 SFINAE が使用されます)。この C++ 手法の詳細については、wikipediaまたはcppreference.comを参照してください。

C++20 では、概念によってこれがはるかに簡単になり、インターフェイスが台無しになりません。

#include <concepts>

template<typename T>
concept arithmetic = std::integral<T> or std::floating_point<T>;

template<typename T>
  requires arithmetic<T>
struct S{};
// Shorthand: template<arithmetic T> struct S {};

ただし、算術的に使用することを意図した多くのユーザー型があることに注意してください。そのため、探しているではなく、探している操作をカバーするより一般的な概念が汎用インターフェイスで望ましいでしょう。

于 2013-01-12T14:29:39.163 に答える
25

アプローチから受け取ったエラーメッセージは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
}
于 2016-05-10T18:05:50.380 に答える