问题 公共继承的静态断言


我构建了一个帮助类,它将通过模板构建一个自定义类,这个自定义类必须从某个类继承,我可以检查这个 std::is_base_of

但是我还需要检查继承是否公开,如何实现?

作为参考,这里是一个精简版的类,我有 std::is_base_of 在那里。

template<class CustomSink>
class Sink
{
    static_assert(std::is_base_of<BaseSink, CustomSink>::value, "CustomSink must derive from BaseSink");
    //Some static assert here to check if custom sink has publicly inherited BaseSink 
    //static_assert(is_public.....
public:
    template<class... Args>
    Sink(Args&&... args)
    {
    }
    ~Sink()
    {
    }       
};

9424
2018-05-24 12:49


起源



答案:


据我所知,公共继承是唯一可以执行隐式指针转换的情况(可以通过重载运算符实现引用转换)。

template <class T>
std::true_type is_public_base_of_impl(T*);

template <class T>
std::false_type is_public_base_of_impl(...);

template <class B, class D>
using is_public_base_of = decltype(is_public_base_of_impl<B>(std::declval<D*>()));

在Coliru现场观看


9
2018-05-24 12:58



或者只是使用 std::is_convertible<B*, D*>? - cpplearner


答案:


据我所知,公共继承是唯一可以执行隐式指针转换的情况(可以通过重载运算符实现引用转换)。

template <class T>
std::true_type is_public_base_of_impl(T*);

template <class T>
std::false_type is_public_base_of_impl(...);

template <class B, class D>
using is_public_base_of = decltype(is_public_base_of_impl<B>(std::declval<D*>()));

在Coliru现场观看


9
2018-05-24 12:58



或者只是使用 std::is_convertible<B*, D*>? - cpplearner


感谢两者 昆汀 和 cpplearner 指出我正确的方向。我发现 Quentins 如果断言应该通过,则回答工作正常,但是在失败的情况下,static_assert不会捕获错误,而是会在模板内部生成,从而消除了清除的好处 static_assert 信息。

然后 cpplearner 提到 std::is_convertible 我之前尝试过使用但却忘记了需要的东西 *,B和D似乎是错误的方式。

所有这些都促使我创造:

static_assert(std::is_convertible<Derived*, Base*>::value, "Derived must inherit Base as public");

这似乎做了这个工作,下面是完整的代码作为一个完整的例子。

#include <type_traits>

class Base { };
class Derived : Base { };
class DerivedWithPublic : public Base { };

int main() {
    static_assert(std::is_convertible<DerivedWithPublic*, Base*>::value, "Class must inherit Base as public");
    static_assert(std::is_convertible<Derived*, Base*>::value, "Derived must inherit Base as public");
}

2
2018-05-24 23:29