2017-05-24 112 views
10

我建立了一个帮助类,它将通过模板构造一个自定义类,这个自定义类必须继承某个类,我可以用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() 
    { 
    }  
}; 

回答

1

由于双方Quentincpplearner指着我在正确的方向。我发现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"); 
} 
9

据我所知,公共继承是能够执行一个隐含的指针转换(基准转换可以通过重载运算符来实现)的唯一情况。

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*>())); 

See it live on Coliru

+3

或者只是使用'std :: is_convertible '? – cpplearner