gpt4 book ai didi

c++ - 不直接继承的基模板类成员的可见性

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:40 24 4
gpt4 key购买 nike

访问模板基类的成员需要语法 this->memberusing指示。此语法是否也扩展到不直接继承的基模板类?

考虑以下代码:

template <bool X>
struct A {
int x;
};

template <bool X>
struct B : public A<X> {
using A<X>::x; // OK even if this is commented out
};

template <bool X>
struct C : public B<X> {
// using B<X>::x; // OK
using A<X>::x; // Why OK?
C() { x = 1; }
};

int main()
{
C<true> a;

return 0;
}

自模板类的声明B包含 using A<X>::x , 自然是派生模板类 C可以访问xusing B<X>::x .尽管如此,在 g++ 8.2.1 和 clang++ 6.0.1 上,上面的代码编译得很好,其中 xC 中访问用using拿起x直接来自 A

我本以为C无法直接访问A .另外,注释掉 using A<X>::xB仍然使代码编译。连注释掉的组合using A<X>::xB同时在 C 就业using B<X>::x而不是 using A<X>::x给出编译的代码。

代码是否合法?

添加

更清楚一点:问题出现在模板 类上,它与模板类继承的成员的可见性有关。通过标准的公共(public)继承,A 的公共(public)成员可以访问 C , 所以使用语法 this->xC确实可以访问 A<X>::x .但是using呢?指示?编译器如何正确解析 using A<X>::x如果A<X>不是 C 的直接基础?

最佳答案

您正在使用 A<X>需要基类的地方。

[namespace.udecl]

3 In a using-declaration used as a member-declaration, each using-declarator's nested-name-specifier shall name a base class of the class being defined.

由于它出现在需要类类型的地方,所以它是已知的并被假定为一种类型。而且它是一种依赖于模板参数的类型,因此不会立即查找。

[temp.res]

9 When looking for the declaration of a name used in a template definition, the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) are used for non-dependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known ([temp.dep]).

所以它是允许的,因为编译器无法更好地了解。它会在实例化类时检查 using 声明。实际上,可以将任何依赖类型放在那里:

template<bool> struct D{};

template <bool X>
struct C : public B<X> {
using D<X>::x;
C() { x = 1; }
};

直到X的值才会被检查众所周知。因为B<X>专一的话可以带来各种惊喜。例如,可以这样做:

template<>
struct D<true> { char x; };

template<>
struct B<true> : D<true> {};

使上述声明正确。

关于c++ - 不直接继承的基模板类成员的可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56254353/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com