120

テンプレート関数と2つのクラスがあるとします

class animal {
}
class person {
}

template<class T>
void foo() {
  if (T is animal) {
    kill();
  }
}

Tが動物であるかどうかを確認するにはどうすればよいですか?実行時にチェックするものは必要ありません。ありがとう

4

5 に答える 5

161

使用is_same

#include <type_traits>

template <typename T>
void foo()
{
    if (std::is_same<T, animal>::value) { /* ... */ }  // optimizable...
}

通常、それは完全に実行不可能な設計ですが、あなたは本当に専門にしたいです:

template <typename T> void foo() { /* generic implementation  */ }

template <> void foo<animal>()   { /* specific for T = animal */ }

また、明示的な(推論されていない)引数を持つ関数テンプレートがあることは珍しいことにも注意してください。これは前代未聞ではありませんが、多くの場合、より良いアプローチがあります。

于 2012-11-29T23:18:22.080 に答える
47

今日は、C ++ 17でのみ使用する方が良いと思いますが、

#include <type_traits>

template <typename T>
void foo() {
    if constexpr (std::is_same_v<T, animal>) {
        // use type specific operations... 
    } 
}

if式本体で。を指定せずにタイプ固有の操作を使用するconstexprと、このコードはコンパイルされません。

于 2018-02-07T18:20:57.880 に答える
7

次のように、パラメータに渡された内容に基づいてテンプレートを特殊化できます。

template <> void foo<animal> {

}

これにより、として渡された型に基づいてまったく新しい関数が作成されることに注意してくださいT。これは、煩雑さを軽減し、基本的に最初にテンプレートを使用する理由であるため、通常は望ましい方法です。

于 2012-11-29T23:17:13.577 に答える
6

C ++ 17では、バリアントを使用できます。

を使用std::variantするには、ヘッダーを含める必要があります。

#include <variant>

その後、次std::variantのようにコードを追加できます。

using Type = std::variant<Animal, Person>;

template <class T>
void foo(Type type) {
    if (std::is_same_v<type, Animal>) {
        // Do stuff...
    } else {
        // Do stuff...
    }
}
于 2018-06-27T09:57:54.453 に答える
3

std::is_same()C++11以降でのみ使用できます。C ++ 11より前の場合は、以下を使用できますtypeid()

template <typename T>
void foo()
{
    if (typeid(T) == typeid(animal)) { /* ... */ }
}
于 2021-01-28T07:33:00.913 に答える