确保一个类不从两个接口继承

时间:2020-07-11 08:12:36

标签: c++ c++14

我有这个问题。我们开发并使用了一个框架。我们有一些该框架的用户需要实现的接口。我想确保这些接口中的两个永远不能在同一类上实现。这是一个例子

class A{
  void a() = 0;
};
class B{
  void b() = 0;
};

class C: public A, public B { // This should give error
};
class D: public A{ // OK
};

到目前为止,我想也许我可以使用static_assertstd::is_convertible,但是我不能动手做它。

编辑: 我不知道谁会写派生类,所以如果可能的话,我想在基础接口中使用它。基本上假设我无权访问派生类,因为它们不在我们的代码库中。

谢谢。

1 个答案:

答案 0 :(得分:2)

这样写自己的特征:

template<typename Derived, typename... BaseCandidates>
struct has_no_base;

template<typename Derived>
struct has_no_base<Derived>
    : std::true_type { };

template<typename Derived, typename BaseFirst, typename... BasesRest>
struct has_no_base<Derived, BaseFirst, BasesRest...>
    : std::conditional_t<
        std::is_base_of<BaseFirst, Derived>,
        std::true_type,
        has_no_base<Derived, BasesRest...>
      > { };

template<typename Derived, typename... PossibleBases>
struct has_only_one_base;

template<typename Derived>
struct has_only_one_base<Derived>
    : std::false_type { };

template<typename Derived, typename Base>
struct has_only_one_base<Derived, Base>
    : std::conditional_t<
        std::is_base_of_v<Base, Derived>,
        std::true_type,
        std::false_type
      > { };

template<typename Derived, typename BaseFirst, typename... BasesRest>
struct has_only_one_base<Derived, BaseFirst, BasesRest...>
    : std::conditional_t<
        std::is_base_of_v<BaseFirst, Derived>,
        has_no_base<Derived, BasesRest...>,
        has_only_one_base<Derived, BasesRest...>
      > { };

并像这样使用它:

class MyClass : public A, public B
{
    static_assert(has_only_one_base<MyClass, A, B>::value, "Error");
};

此外,就您是此框架的开发者而言,您可以提供一些检查特征:

template<typename Type>
using is_valid_class = has_only_one_base<Type, IFirst, ISecond, ... ILast>;

并使用它:

class MyClass : public A, public B
{
    static_assert(is_valid_class<MyClass>::value, "Error");
};