템플릿 매개 변수의 유형을 확인하는 방법은 무엇입니까?


97

템플릿 함수와 두 개의 클래스가 있다고 가정합니다.

class animal {
}
class person {
}

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

T가 동물인지 어떻게 확인하나요? 런타임 중에 확인하는 것을 원하지 않습니다. 감사


61
나는 :-) 대신 "죽"의 "애완 동물"둘 것
JimBamFeng

답변:


135

사용 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 */ }

또한 명시 적 (추론되지 않은) 인수가있는 함수 템플릿이있는 경우는 드뭅니다. 전례가 없지만 종종 더 나은 접근 방식이 있습니다.


2
고마워! 난 정말 그것을 복제 할 수 없습니다, 그래서 실제로 많은 코드를 공유
WhatABeautifulWorld

3
@WhatABeautifulWorld : 유형 종속 부분이 특수 기능으로 강등 될 수 있도록 항상 코드를 팩터링 할 수 있습니다.
Kerrek SB

1
한 번의 빠른 후속 조치로 std :: is_same을 사용하면 다른 템플릿 매개 변수에 대한 코드 속도가 느려지지 않습니다.
WhatABeautifulWorld 2011

1
@WhatABeautifulWorld : 특성 값은 모두 정적으로 알려져 있습니다. 컴파일러가 반 정도 괜찮다면 런타임 비용이 없어야합니다. 의심스러운 경우 어셈블리를 확인하십시오.
Kerrek SB

2
@ AdriC.S .: T추론되지 않았으므로 할 수있는 일이 많지 않습니다. 기본 템플릿을 구현되지 않은 상태로두고 전문화를 만들거나 is_same.
Kerrek SB 2014 년

37

나는 오늘날 사용하는 것이 더 낫다고 생각하지만 C ++ 17에서만 사용합니다.

#include <type_traits>

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

if 표현식 본문에서를 사용하지 않고 일부 유형별 연산을 사용하면 constexpr이 코드가 컴파일되지 않습니다.


8
대신 std::is_same<T, U>::value더 짧게 사용할 수 있습니다.std::is_same_v<T, U>
Fureeish

12

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...
    }
}

8
T와 Type은 어떻게 연결 되나요?
mabraham

4
이 답변은 여러면에서 문제가 있습니다. 실제 오류 ( 여기서는 의미가없는 type유형 Type또는 템플릿 의 값 ) is_same_v외에는 variant. 해당 "특성"은 holds_alternative입니다.
Pixelchemist

std::variant여기에서 완전히 불필요합니다
tjysdsg

7

다음과 같이 매개 변수에 전달되는 내용을 기반으로 템플릿을 전문화 할 수 있습니다.

template <> void foo<animal> {

}

이렇게하면 T. 이것은 일반적으로 혼란을 줄이고 본질적으로 우리가 처음에 템플릿을 사용하는 이유이기 때문에 바람직합니다.


흠. 이 방법이 템플릿 인수를 전문화하는 유일한 방법입니까? 템플릿 함수 내에서 관리해야하는 10 개의 다른 자식 클래스가 있다고 가정 해 보겠습니다. 각 클래스에 대해 10 개의 다른 템플릿 함수를 작성해야합니까? 여기서 핵심 포인트를 놓치고있는 것 같습니다.
Volkan Güven

누군가 type_traits를 사용하고 싶지 않다면 이것은 정말 좋은 생각처럼 들립니다. 누군가가 언급했듯이 주 논리는 유형을 나타내는 추가 플래그를 허용하는 다른 함수에서 수행 될 수 있으며이 특수 선언은 그에 따라 플래그를 설정하고 아무것도 건드리지 않고 다른 모든 인수를 직접 전달할 수 있습니다. 따라서 10 개의 다른 클래스를 처리해야하는 경우 기본적으로 10 개의 다른 함수 정의에 대해 10 줄입니다. 그러나 하나 이상의 템플릿 변수가 있으면 이것은 훨씬 복잡해질 것입니다.
Harish Ganesan 2019 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.