템플릿 매개 변수 T
를 특정 클래스의 하위 클래스로 지정하려면 Baseclass
어떻게해야합니까? 이 같은:
template <class T : Baseclass> void function(){
T *object = new T();
}
답변
이 경우 다음을 수행 할 수 있습니다.
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 환경에서도 작동해야합니다.
답변
런타임에 덜 쓸모없는 코드를 실행하려면 다음을 참조하십시오 .
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>();
}
답변
개념은 필요하지 않지만 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
}
이는 조건이 충족 될 때만 함수를 인스턴스화하지만 조건이 충족되지 않으면 현명한 오류를 제공하지 않습니다.
답변
C ++ 11부터 Boost 또는 static_assert
. C ++ 11은 is_base_of
및 enable_if
. C ++ 14에는 편의 유형이 도입 enable_if_t
되었지만 C ++ 11을 사용 enable_if::type
하는 경우 간단히 대신 사용할 수 있습니다 .
대안 1
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
}
대안 2
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
}
대안 3
전체 템플릿을 제한 할 수도 있습니다. 이 방법을 사용하여 전체 클래스를 정의 할 수 있습니다. 의 두 번째 매개 변수가 어떻게 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
.
답변
당신이 사용할 수있는 부스트 개념 확인 ‘들 BOOST_CONCEPT_REQUIRES
:
#include <boost/concept_check.hpp>
#include <boost/concept/requires.hpp>
template <class T>
BOOST_CONCEPT_REQUIRES(
((boost::Convertible<T, BaseClass>)),
(void)) function()
{
//...
}
답변
기본 클래스에있는 템플릿 내부의 함수를 호출합니다.
이 함수에 액세스 할 수없는 유형으로 템플릿을 인스턴스화하려고하면 컴파일 타임 오류가 발생합니다.