템플릿 함수와 두 개의 클래스가 있다고 가정합니다.
class animal {
}
class person {
}
template<class T>
void foo() {
if (T is animal) {
kill();
}
}
T가 동물인지 어떻게 확인하나요? 런타임 중에 확인하는 것을 원하지 않습니다. 감사
템플릿 함수와 두 개의 클래스가 있다고 가정합니다.
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
. 이것은 일반적으로 혼란을 줄이고 본질적으로 우리가 처음에 템플릿을 사용하는 이유이기 때문에 바람직합니다.