是' typedef'在C ++类中自动继承?

时间:2016-05-13 09:41:10

标签: c++ c++11

我曾经相信' typedef'不会自动继承。但是下面的代码表示不同的东西。

#include <iostream>
#include <type_traits>

struct A
{
    typedef int X;
};

struct A_ 
{
    typedef char X;
};

struct B : A {};
struct B_ : A, A_ {};

template< typename ... Ts >
using void_t = void;

template< typename T, typename = void >
struct has_typedef_X : std::false_type {};

template< typename T >
struct has_typedef_X< T, void_t<typename T::X> > : std::true_type {};

int main()
{
    std::cout << std::boolalpha;
    std::cout << has_typedef_X<A>::value << std::endl;
    std::cout << has_typedef_X<A_>::value << std::endl;
    std::cout << has_typedef_X<B>::value << std::endl;
    std::cout << has_typedef_X<B_>::value << std::endl;
    return 0;
}

输出为'true true true false&#39;。 但在我看来,&#39; has_typedef_X<B>::value&#39;给予真实的&#39;暗示在结构B中,X是&#39; typedef&#39; ed。

所以,如果有人能解释这个问题或纠正我吗?

http://melpon.org/wandbox/permlink/iwZ6eZ3PoBPgyFBj [已更正网址]

提供在线版本

3 个答案:

答案 0 :(得分:10)

父类的嵌套类型名称(即成员类型)在派生类的范围内是可见的,只要访问说明符不是私有的,就可以访问它们。如果不同的基类中有多个具有相同名称的类型,则非限定名称不明确。

我发现的最相关的标准报价是:

[class.nested.type] §1

  

类型名称遵循与其他名称完全相同的范围规则。 [...]

[class.member.lookup] §9

  

[注意:即使一个对象有多个基类,也可以明确地找到基类T中定义的静态成员嵌套类型或枚举器 T型子对象[...]

实际上,使用它的一个示例是标准,它指定标准容器的迭代器继承std::iterator模板,该模板只包含嵌套类型名称。继承的重点是将这些嵌套类型名称添加到迭代器中。 (此示例将在下一个标准版本(c ++ 17)中过时,建议不再使用std::iterator。)

答案 1 :(得分:2)

X适用于BB_的范围,B_的问题是B_::X不明确,因此模板扣除失败了has_typedef将假名作为唯一匹配。

答案 2 :(得分:2)

由于名称X由于在两个基类中定义而不明确,因此导致B_has_typedef的模板扣除失败。

您认为typedef不是继承的可能来自某些C ++专业,在非限定名称查找期间,不考虑基类。 见Propagating 'typedef' from based to derived class for 'template'