在具有相同值的多重继承中通过不同的基查找相同的名称

问题描述 投票:0回答:1

假设我有一个继承自两个不同类的类。他们都有一个像

using type_alias = int;
这样的别名。在班级范围内查找
type_alias
应该是
int
还是模棱两可?如果两个不同的类都从同一个类继承了该类型别名怎么办?

这里有一些其他的例子:

enum enum_type {
    enumerator
};

template<int>
struct base {
    using type_alias = int;
    using enum enum_type;
};

struct derived : base<0>, base<1> {};

derived::type_alias main() {
    return derived::enumerator;
}

derived::base<2> x;  // injected-class-name
template<int>
struct super_base_template {};

struct super_base : super_base_template<0> {
    using type_alias = int;
    enum enum_type {
        enumerator
    };
    static constexpr int static_member = 2;
};


template<int>
struct base : super_base {};

struct derived : base<0>, base<1> {};

derived::type_alias main() {
    return derived::enumerator;
}

derived::super_base_template<derived::static_member> x;

clang 似乎能够编译所有这些,而 gcc 只喜欢它们是从字面上相同的声明继承的,例如第二个片段和第一个片段的最后一行。

以下哪些是有效的查找?

c++ language-lawyer multiple-inheritance name-lookup
1个回答
1
投票

[class.member.lookup] 描述了如何在类的范围内搜索名称。与这个问题相关的部分是p5.2:

  • 否则,如果 S(N, Bi)S(N,C) 的声明集不同,则合并是不明确的...

对于表示同一实体的不同声明,措辞也不例外;即使找到的两个声明都是

using type_alias = int;
,查找也是不明确的。相反,如果只有一个声明(源自同一个基类),则该声明是查找的明确结果:

struct A { using X = int; };
struct B : A { using Y = int; };
struct C : A { using Y = int; };
struct D : B, C {};
D::X x; // OK
D::Y y; // ambiguous

关于具体示例:在第一个片段中,

  • derived::type_alias
    如上所述是模棱两可的,
  • derived::enumerator
    明确引用了第二行
    enumerator
    的声明:
    using enum enum_type;
    等价于
    using enum_type::enumerator;
    [enum.udecl]/2),查找时替换using-declarators通过他们命名的声明 ([basic.lookup.general]/3),
  • derived::base
    明确指代类模板
    base
    [temp.local]/4.

在第二个片段的

derived::
中,每次查找都会找到一个声明,因此那里没有歧义。

© www.soinside.com 2019 - 2024. All rights reserved.