템플릿 매개 변수 T를 특정 클래스의 하위 클래스로 지정하려면 Baseclass어떻게해야합니까? 이 같은:
template <class T : Baseclass> void function(){
T *object = new T();
}
템플릿 매개 변수 T를 특정 클래스의 하위 클래스로 지정하려면 Baseclass어떻게해야합니까? 이 같은:
template <class T : Baseclass> void function(){
T *object = new T();
}
T에서 파생 되었는지 여부를 확인하는 것이 좋습니다 Baseclass. 현재이 검사는 암시 적이며 과부하 해결에 표시되지 않습니다. 그러나 그러한 암시 적 제약이 어디에도 수행되지 않으면 인위적인 제한의 이유가없는 것으로 보입니다.
답변:
이 경우 다음을 수행 할 수 있습니다.
template <class T> void function(){
Baseclass *object = new T();
}
T가 Baseclass의 서브 클래스가 아니면 (또는 T 가 Baseclass) 컴파일되지 않습니다 .
C ++ 11 호환 컴파일러를 사용하면 다음과 같이 할 수 있습니다.
template<class Derived> class MyClass {
MyClass() {
// Compile-time sanity check
static_assert(std::is_base_of<BaseClass, Derived>::value, "Derived not derived from BaseClass");
// Do other construction related stuff...
...
}
}
CYGWIN 환경에서 gcc 4.8.1 컴파일러를 사용하여 이것을 테스트 했으므로 * nix 환경에서도 작동해야합니다.
template<class TEntity> class BaseBiz { static_assert(std::is_base_of<BaseEntity, TEntity>::value, "TEntity not derived from BaseEntity");...
런타임에 덜 쓸모없는 코드를 실행하려면 다음을 참조하십시오 . http://www.stroustrup.com/bs_faq2.html#constraints 는 컴파일 시간 테스트를 효율적으로 수행하고 더 좋은 오류 메시지를 생성하는 일부 클래스를 제공합니다.
특히:
template<class T, class B> struct Derived_from {
static void constraints(T* p) { B* pb = p; }
Derived_from() { void(*p)(T*) = constraints; }
};
template<class T> void function() {
Derived_from<T,Baseclass>();
}
unused variable 'p'와는 unused variable 'pb'?
(void)pb;뒤에 추가하십시오 B* pb = p;.
개념은 필요하지 않지만 SFINAE를 사용할 수 있습니다.
template <typename T>
boost::enable_if< boost::is_base_of<Base,T>::value >::type function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
이는 조건이 충족 될 때만 함수를 인스턴스화하지만 조건이 충족되지 않으면 현명한 오류를 제공하지 않습니다.
enable_if해당 디폴트 매개 변수를 두 번째 형식을 사용합니다 void. 표현식 enable_if< true, int >::type은 유형을 나타냅니다 int. 첫 번째 질문이 무엇인지 정말 이해할 수 없습니다. SFINAE를 원하는대로 사용할 수 있지만 모든 기능에 대해 이것으로 무엇을 하려는지 잘 이해하지 못합니다.
C ++ 11부터 Boost 또는 static_assert. C ++ 11은 is_base_of 및 enable_if. C ++ 14에는 편의 유형이 도입 enable_if_t되었지만 C ++ 11을 사용 enable_if::type하는 경우 간단히 대신 사용할 수 있습니다 .
David Rodríguez 의 솔루션은 다음과 같이 다시 작성할 수 있습니다.
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of<Base, T>::value, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
C ++ 17부터 is_base_of_v. 솔루션은 다음과 같이 다시 작성할 수 있습니다.
#include <type_traits>
using namespace std;
template <typename T>
enable_if_t<is_base_of_v<Base, T>, void> function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
전체 템플릿을 제한 할 수도 있습니다. 이 방법을 사용하여 전체 클래스를 정의 할 수 있습니다. 의 두 번째 매개 변수가 어떻게 enable_if_t제거되었는지 확인하십시오 (이전에 void로 설정 됨). 기본값은 실제로 void이지만 사용하지 않기 때문에 중요하지 않습니다.
#include <type_traits>
using namespace std;
template <typename T,
typename = enable_if_t<is_base_of_v<Base, T>>>
void function() {
// This function will only be considered by the compiler if
// T actualy derived from Base
}
로부터 문서 템플릿 매개 변수의, 우리는 그 볼 typename = enable_if_t...빈 이름을 가진 템플릿 매개 변수입니다. 우리는 단순히 타입의 정의가 존재하는지 확인하기 위해 그것을 사용하고 있습니다. 특히 는의 밑이 아닌 enable_if_t경우 정의 Base되지 않습니다 T.
위의 기술은 enable_if.
template <class T : Base>
기본 클래스에있는 템플릿 내부의 함수를 호출합니다.
이 함수에 액세스 할 수없는 유형으로 템플릿을 인스턴스화하려고하면 컴파일 타임 오류가 발생합니다.
T A는 BaseClass 에서 선언 된 회원이 때문에 BaseClass의 선언에 반복 될 수있다 T.