programing

C ++ 템플릿 매개 변수를 하위 클래스로 제한

nasanasas 2020. 11. 3. 08:06
반응형

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_ofenable_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

반응형