繁体   English   中英

std :: enable_if,模板特化和继承

[英]std::enable_if, template specialization and inheritance

我想问你关于这段代码的一些建议。 它有效,但我认为它可以用更优雅的方式编写。 这是一段C ++ 11代码,所以在编译时请记住它;)!

#include <iostream>
#include <type_traits>
#include <typeinfo>

using namespace std;

class A {};
class B: public A {};

class C {};
class D: public C {};

class E: public A, public C {};

template<class T, typename = void>
class Example;

template<class T>
class Example<T, typename enable_if<is_base_of<A, T>::value and not is_base_of<C, T>::value>::type>
{
  public:
    string a() const
    {
      return string(typeid(T).name()) + " have A as base class";
    }
};

template<class T>
class Example<T, typename enable_if<not is_base_of<A, T>::value and is_base_of<C, T>::value>::type>
{
  public:
    string b() const
    {
      return string(typeid(T).name()) + " have C as base class";
    }
};

template<class T>
class Example<T, typename enable_if<is_base_of<A, T>::value and is_base_of<C, T>::value>::type> :
    public Example<A>,
    public Example<C>
{
};

int
main()
{
  Example<B> example1;
  Example<D> example2;
  Example<E> example3;

  cout << example1.a() << endl;
  //cout << example1.b() << endl;   It must raise a compile error
  //cout << example2.a() << endl;   It must raise a compile error
  cout << example2.b() << endl;
  cout << example3.a() << endl;
  cout << example3.b() << endl;
}

正如您所看到的,我正在尝试编写一个可以处理从AC派生的类的类模板。 问题是当AC继承为E类时。 事实上我们也可能有这样的东西......

template<class T>
class Example<T, typename enable_if<is_base_of<A, T>::value> { /* ... */ };

template<class T>
class Example<T, typename enable_if<is_base_of<C, T>::value> { /* ... */ };

...但是当一个类(如E )继承AC时它会失败。

有没有更好的代码的想法? 谢谢

更简单的方法是使用static_assert

template <typename T>
class Example
{
public:
    std::string a() const
    {
        static_assert(std::is_base_of<A, T>::value, "T must derive from A to use a()");
        return std::string(typeid(T).name()) + " have A as base class";
    }

    std::string b() const
    {
        static_assert(std::is_base_of<C, T>::value, "T must derive from C to use b()");
        return std::string(typeid(T).name()) + " have C as base class";
    }
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM