检查C++类是否公开继承了带有匿名参数的模板类

Kyl*_*ick 4 c++ inheritance templates c++11 c++14

此问题类似,如何在不指定模板参数的情况下测试类是否Impl公开继承模板类BaseTempl(即class Impl : public BaseTempl< ... >{ ... };)?

但是,与上述问题不同,如果继承不是公共的,我希望测试仍然编译(并返回false).

理想情况下,代码允许我做这样的事情:

class alpha : public BaseTempl< int >{};

class bravo : BaseTempl< int >{};

class charlie{};

class delta : public BaseTempl< int >, public charlie {};

class echo : public delta {};

int main(){
    publicly_inherits_from < alpha,   BaseTempl > (); // true
    publicly_inherits_from < bravo,   BaseTempl > (); // false
    publicly_inherits_from < charlie, BaseTempl > (); // false
    publicly_inherits_from < delta,   BaseTempl > (); // true
    publicly_inherits_from < echo,    BaseTempl > (); // true
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译上面的代码时,链接问题的答案给出了以下错误:

error: ‘BaseTempl<int>’ is an inaccessible base of ‘bravo’
Run Code Online (Sandbox Code Playgroud)

Sam*_*hik 5

以下SFINAE基于方法的方法似乎产生了预期的结果.作为额外的奖励,BaseTempl模板可以采用可变参数,而不仅仅是一个参数:

#include <iostream>

template<typename ...Args> class BaseTempl {};

template<typename T> class inherits_from_basetempl {

public:

    template<typename ...Args>
    static const bool sfinae_param(const BaseTempl<Args...> &a);

    template<typename V=T>
    static constexpr auto is_inherits(int)
        -> decltype(sfinae_param(std::declval<V &>()))
    {
        return true;
    }

    static constexpr bool is_inherits(...)
    {
        return false;
    }

    static const bool value=is_inherits(0);
};

class alpha : public BaseTempl< int >{};

class bravo : BaseTempl< int >{};

class charlie{};

class delta : public BaseTempl< int >, public charlie {};

class echo : public delta {};

int main()
{
    std::cout << inherits_from_basetempl<alpha>::value << std::endl;
    std::cout << inherits_from_basetempl<bravo>::value << std::endl;
    std::cout << inherits_from_basetempl<charlie>::value << std::endl;
    std::cout << inherits_from_basetempl<delta>::value << std::endl;
    std::cout << inherits_from_basetempl<echo>::value << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

结果:

$ gcc --version
gcc (GCC) 5.3.1 20151207 (Red Hat 5.3.1-2)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -std=c++14 -o t t.C 2>&1 | less
$ ./t
1
0
0
1
1
Run Code Online (Sandbox Code Playgroud)