C ++ 템플릿 매개 변수를 하위 클래스로 제한
템플릿 매개 변수 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
}
이는 조건이 충족 될 때만 함수를 인스턴스화하지만 조건이 충족되지 않으면 현명한 오류를 제공하지 않습니다.
당신이 사용할 수있는 부스트 개념 확인 '들 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()
{
//...
}
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
You could also just restrict the the whole template. You could use this method for defining whole classes. Note how the second parameter of enable_if_t
has been removed (it was previously set to void). Its default value is actually void
, but it doesn't matter, as we are not using it.
#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
}
From the documentation of template parameters, we see that typename = enable_if_t...
is a template parameter with an empty name. We are simply using it to ensure that a type's definition exists. In particular, enable_if_t
will not be defined if Base
is not a base of T
.
The technique above is given as an example in enable_if
.
By calling functions inside your template that exist in the base class.
If you try and instantiate your template with a type that does not have access to this function, you will receive a compile-time error.
참고URL : https://stackoverflow.com/questions/3175219/restrict-c-template-parameter-to-subclass
'programing' 카테고리의 다른 글
JavaScript / jQuery를 사용하여 ASP.NET MVC의 다른 페이지로 리디렉션 (0) | 2020.11.03 |
---|---|
Internet Explorer 엔진을 사용할 수 없기 때문에 응답 콘텐츠를 구문 분석 할 수 없습니다. (0) | 2020.11.03 |
gradle (1.1.2-5)로 빌드하는 데 사용되는 kotlin 버전이 IDE 플러그인 (1.1.2-4)에 번들로 제공되는 버전과 다릅니다. (0) | 2020.11.03 |
조인 및 행 기반 제한 (페이징)을 사용하여 최대 절전 모드에서 고유 한 결과를 얻는 방법은 무엇입니까? (0) | 2020.11.03 |
UITextField 예측 텍스트 비활성화 (0) | 2020.11.03 |