テンプレート関数と2つのクラスがあるとします
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
Tが動物かどうかの確認方法を教えてください。実行時にチェックするものは必要ありません。ありがとう
テンプレート関数と2つのクラスがあるとします
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
Tが動物かどうかの確認方法を教えてください。実行時にチェックするものは必要ありません。ありがとう
回答:
使用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 */ }
また、明示的な(推論されていない)引数を持つ関数テンプレートを使用することは珍しいことにも注意してください。それは前例のないことではありませんが、多くの場合、より良いアプローチがあります。
T
は推定されないため、実行できることはあまりありません。プライマリテンプレートを未実装のままにして特殊化を作成するか、で静的アサーションを追加できますis_same
。
今日は、C ++ 17でのみ使用する方が良いと思います。
#include <type_traits>
template <typename T>
void foo() {
if constexpr (std::is_same_v<T, animal>) {
// use type specific operations...
}
}
なしのif式本体でタイプ固有の操作を使用するとconstexpr
、このコードはコンパイルされません。
std::is_same<T, U>::value
より短いものを使用することができます:std::is_same_v<T, U>
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...
}
}
type
タイプの値Type
またはここでis_same_v
は意味をなさないテンプレート)に加えて、のコンテキストでは意味がありませんvariant
。対応する「特性」はholds_alternative
です。
std::variant
ここではまったく不要です
次のように、パラメータに渡される内容に基づいてテンプレートを特化できます。
template <> void foo<animal> {
}
これは、として渡されるタイプに基づいて、まったく新しい関数を作成することに注意してくださいT
。これは、混乱を減らすため、通常は望ましい方法であり、基本的にはそもそもテンプレートを用意している理由です。