C ++ 11是否支持模板类反射?

时间:2015-10-02 01:33:51

标签: c++ c++11

我对C ++ 11模板有一点了解。我的目的是拥有一个模板函数,如下所示:

template<class T>
void function(T * a) {
  if (T belongs to class M) {
    a->function_m();
  } else {
    a->function_o();
  }
}

C ++ 11是否支持此模板类反射?

4 个答案:

答案 0 :(得分:5)

是的,更好的是,您不需要执行if(...){} else{}语句来执行此操作。您可以使用标记分派或特化来避免条件语句。以下示例使用标记分派。

示例:

#include <iostream>
#include <type_traits>

template <typename B, typename D>
void function( D* a )
{
    function( a, typename std::is_base_of<B, D>::type{} );
}

template <typename T>
void function( T* a, std::true_type )
{
    a->function_b();
}

template <typename T>
void function( T* a, std::false_type )
{
    a->function_c();
}

struct B
{
    virtual void function_b() { std::cout << "base class.\n"; }
};

struct D : public B
{
    void function_b() override { std::cout << "derived class.\n"; }
};

struct C
{
    void function_c() { std::cout << "some other class.\n"; }
};

int main()
{
    D d;
    C c;
    function<B, D>( &d );
    function<B, C>( &c );
}

此机制不要求两个函数在同一范围内可见。

答案 1 :(得分:3)

有几种选择:

  • SFINAE:

    template<class T>
    std::enable_if_t<std::is_base_of<M, T>>
    function(T* a)
    {
        a->function_m();
    }
    
    template<class T>
    std::enable_if_t<!std::is_base_of<M, T>>
    function(T* a)
    {
        a->function_o();
    }
    
  • 或标签调度:

    namespace details {
        template<class T>
        void function(T* a, std::true_type) {
            a->function_m();
        }
    
        template<class T>
        void function(T* a, std::false_type) {
            a->function_o();
        }
    }
    template<class T>
    void function(T* a)
    {
        details::function(a, std::is_base_of<M, T>{});
    }
    

答案 2 :(得分:1)

是的,std::is_base_of<Base,Derived>

template<class T>
void function(T * a) {
  if (std::is_base_of<M,T>::value) {
    a->function_m();
  } else {
    a->function_o();
  }
}

但是,在这种情况下可能会导致问题,因为function_m()function_o()都需要可以调用。

答案 3 :(得分:0)

你想要什么可以用c ++ 17

完成
template <typename T>
void function( T* a )
{
    if constexpr (std::is_base_of<M,T>::value)
        a->function_m();
    else
        a->function_o();
}

完整示例:http://melpon.org/wandbox/permlink/MsHnYQNlBcRhTu2C 正如@Fabio Fracassi所提到的

相关问题