c++ - 当基类是模板时,访问基类时的不同行为

标签 c++ templates inheritance

当我写A::B::C时,与 A是一个类,并且 B作为它的基类,我假设我正在访问 C这是在该基 B 中定义的。当 B 时,这不起作用。实际上并不是 A 的基础。然而,当 B 时,显然情况并非如此。是一个模板,例如A::B<123>::C仍然给我 B<123>::C ,并且 B<123> 似乎并不重要。实际上是 A 的基数或不。我不知道为什么会有差异。难道不解释A::B<123>作为访问基类 B<123>A ?为什么不?是否可以以某种方式重写它,以便它像访问基类一样解释它?

这是一个片段,详细解释了所做的事情,并带有解释每个步骤的注释:

// Here we show that we can't access a non-existent base of A
namespace WorksAsExpectedWithoutTemplates {

struct B
{
  using C = void;
};

struct D
{
  using C = void;
};

struct A: B
{
};

// Compiles as expected, B is a base of A, so Foo is B::C, aka void
using Foo = A::B::C;

// Doesn't compile, as expected, because D isn't a base of A, even though D::C
// exists
using Bar = A::D::C; // WE DON'T EXPECT THIS TO COMPILE, WHICH IS FINE
}

// Now we try the same thing with templates, and it doesn't behave the same way.
// Why?
namespace ActsDifferentlyWithTemplates {

template< int >
struct B
{
  using C = void;
};

struct A: B< 42 >
{
};

// Compiles as expected, B< 42 > is a base of A, so Foo is B< 42 >::C, aka void
using Foo = A::B< 42 >::C;

// Compiles, Bar is B< 123 >::C, even though B< 123 > is not a base of A. Why
// does this behave differently than in the non-template case above? Can this be
// rewritten differently so that this wouldn't compile, same as in
// WorksAsExpectedWithoutTemplates, since B< 123 > isn't a base of A?
using Bar = A::B< 123 >::C; // WHY DOES THIS COMPILE? B< 123 > isn't a base of A
}

最佳答案

template< int > struct B有一个 injected-class-name B如果它紧接在 < 之前,则充当模板名称。 。类(class)struct A继承了这一点。

所以,A::B< 123 >::CB< 123 >::C 相同,不是基类 B< 42 > 。例如:

template<int X>
struct B {
    using C = char[X];
};

struct A : B<42> {};

using Foo = A::B<42>::C;
using Bar = A::B<123>::C;
using Baz = A::B::C;  // (injected-class-name without template)

static_assert(sizeof(Foo) == 42);
static_assert(sizeof(Bar) == 123);  // This is a different type
static_assert(sizeof(Baz) == 42);

这些情况实际上都不是“访问基类”。它们都像任何其他成员类型别名/成员模板一样从基类继承注入(inject)类名。

关于c++ - 当基类是模板时,访问基类时的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71866374/

相关文章:

c++ - 为什么在没有声明的情况下不从 .cpp 文件中获取模板函数的完全特化?

c++ - boost::bind 在存储时不保存部分参数

C++ 编译时位掩码添加

python - 仅使用静态方法调用继承类的构造函数

c++ - 多层次抽象类

JavaScript子类继承: unexpectedly works even without subclass constructor - why is it needed?

c++ - 在单独的线程中调用 boost::python::object 作为函数

c++ - 阵列最大间隙的计算

Python C++ float 学表示错误

python - {% 扩展 "view/base.html"%}