Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 未替换作用域解析运算符后的模板参数_C++_Templates_Scope Resolution - Fatal编程技术网

C++ 未替换作用域解析运算符后的模板参数

C++ 未替换作用域解析运算符后的模板参数,c++,templates,scope-resolution,C++,Templates,Scope Resolution,我正在尝试生成一个通用代码,如果B不是D的祖先,它将导致编译错误。我想到的是: template<typename B, typename D> struct assert_base_of { enum {value = sizeof(B::D)}; } 看起来模板参数D不能代替A1。有人能解释并建议一个解决方案吗?继承没有将派生类包含在基类的作用域中,因此使用作用域解析操作符没有任何意义。正确的替代方法(也适用于多重继承)是滥用重载解析规则: #include <i

我正在尝试生成一个通用代码,如果B不是D的祖先,它将导致编译错误。我想到的是:

template<typename B, typename D>
struct assert_base_of {
    enum {value = sizeof(B::D)};
}

看起来模板参数D不能代替A1。有人能解释并建议一个解决方案吗?

继承没有将派生类包含在基类的作用域中,因此使用作用域解析操作符没有任何意义。正确的替代方法(也适用于多重继承)是滥用重载解析规则:

#include <iostream>
#include <type_traits>

template<typename Base, typename Derived,
       bool = std::is_same<Base, Derived>::value>
struct is_base_of_impl
{

  typedef typename std::remove_cv<Base>::type     no_cv_base;      
  typedef typename std::remove_cv<Derived>::type  no_cv_derived;


  template<typename _Up>
  static std::true_type test(no_cv_derived&, _Up);
  static std::false_type test(no_cv_base&, int);

  //Black Magic
  struct converter
  {
   operator no_cv_derived&();
   operator no_cv_base&() const;
  };

  static const bool value = decltype(test(converter(), 0))::value;
};

template<typename Base, typename Derived>
struct is_base_of_impl<Base, Derived, true>
{ 
    static const bool value = std::is_same<Base, Derived>::value; 
};

template<typename Base, typename Derived>
struct is_base_of
: public std::integral_constant<bool,
               is_base_of_impl<Base, Derived>::value>
{ };


struct A {};
struct B1 : A {};
struct B2 : A {};
struct C : B1, B2 {};

int main()
{
    std::cout << is_base_of<A, B1>::value << "\n";
    std::cout << is_base_of<B1, C>::value << "\n";
    std::cout << is_base_of<A, C>::value << "\n";
    return 0;
}
#包括
#包括
模板
struct是\u impl的\u base\u
{
typedef typename std::remove_cv::type no_cv_base;
typedef typename std::remove_cv::type no_cv_派生;
模板
静态标准:正确的型式试验(无派生的和,向上);
静态标准:错误的型式试验(无cv基础和int);
//黑魔法
结构转换器
{
运算符no_cv_派生();
运算符no_cv_base&()const;
};
静态常量bool value=decltype(test(converter(),0))::值;
};
模板
struct是\u impl的\u base\u
{ 
静态常量布尔值=std::is_same::value;
};
模板
结构是的基础
:公共标准::积分常数
{ };
结构A{};
结构B1:A{};
结构B2:A{};
结构C:B1,B2{};
int main()
{

std::cout
static\u assert(std::is\u base\u of::value,“B必须是D的基”)
?我不允许使用std::is\u base\u of,即使我可以,我仍然想知道为什么D不会被替换:)
B::D
被解释为成员(不是类型)因为
B
在这里是依赖的。无论如何,你不能得到这样一个基类——你需要从
D
B
投射一个指针,以检查
D
是否继承
B
。请参阅@Veritas答案,了解如何实现
is\u base\u of
B
依赖意味着它依赖于一个模板参数(这里是一个模板参数)。当您编写
B::foo
时,如果
B
是依赖的,则
foo
始终被解释为
B
成员的名称(这是因为编译器会查看您的模板两次,并且在第一次运行时不知道
B
最终会是什么)。如果要
foo
命名类型,则必须使用
typename B::foo
。如果要
foo
命名模板,则必须使用
template B::foo
。此外,您在非模板
sizeof(a::B)
案例中观察到的是
B
的注入类名称(typename
B
被“注入”到
B
,而
A
继承了它--
A::A
也作为一个类型存在)这是C++中的一个暗角,因为它的行为与模板不同。参见和相关的问题。这里重要的是<代码>:::b>代码>命名一个类型,而不是一个成员。我可能是错的,但是在测试之后,我认为您的解决方案对于多重继承不起作用。如果从B1和B2继承,则两者都是错误的。从C继承(非虚拟继承),当我做is_base_of::value时,我得到0。@pyx:You can do
is_base_of::value&&is_base_of::value
。我想这应该更恰当地称为
is_direct_base of
。@Veritas:欢迎来到1k rep!@AlexandreC。我刚刚编辑了答案,这也是libstdc++内部使用的。
main.cpp:16:22: error: ‘D’ is not a member of ‘A2’
#include <iostream>
#include <type_traits>

template<typename Base, typename Derived,
       bool = std::is_same<Base, Derived>::value>
struct is_base_of_impl
{

  typedef typename std::remove_cv<Base>::type     no_cv_base;      
  typedef typename std::remove_cv<Derived>::type  no_cv_derived;


  template<typename _Up>
  static std::true_type test(no_cv_derived&, _Up);
  static std::false_type test(no_cv_base&, int);

  //Black Magic
  struct converter
  {
   operator no_cv_derived&();
   operator no_cv_base&() const;
  };

  static const bool value = decltype(test(converter(), 0))::value;
};

template<typename Base, typename Derived>
struct is_base_of_impl<Base, Derived, true>
{ 
    static const bool value = std::is_same<Base, Derived>::value; 
};

template<typename Base, typename Derived>
struct is_base_of
: public std::integral_constant<bool,
               is_base_of_impl<Base, Derived>::value>
{ };


struct A {};
struct B1 : A {};
struct B2 : A {};
struct C : B1, B2 {};

int main()
{
    std::cout << is_base_of<A, B1>::value << "\n";
    std::cout << is_base_of<B1, C>::value << "\n";
    std::cout << is_base_of<A, C>::value << "\n";
    return 0;
}