2016-05-13 119 views
16

我曾经相信'typedef'不会自动继承。但下面的代码表明了不同的东西。'typedef'在C++类中自动继承吗?

#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'。 但在我看来,'has_typedef_X<B>::value'给'真'意味着在结构B中,X是'typedef'ed。

所以,如果任何人都可以请解释这个问题或纠正我?

一个在线版本可在http://melpon.org/wandbox/permlink/iwZ6eZ3PoBPgyFBj [URL改正]

+0

'T :: X'在'B_'中含糊不清,因此'false'和你的链接似乎破了 –

+0

@PiotrSkotnicki谢谢。我更新了网址。我的问题是结构B,我曾经相信那里没有X typedefed。 –

+2

*“我曾经相信'typedef'不会自动继承。”*那是错误的。 –

回答

8

父类的嵌套类型名称(即成员类型)在派生类的范围内可见,只要访问说明符不是专用的,就可以访问。如果从不同的基类有多个同名的类型,则不合格的名称是不明确的。

的,我发现这方面最相关的标准报价是:

[class.nested.type] §1

类型名称服从完全相同的范围规则的其他名称。 [...]

[class.member.lookup] §9

[注:静态成员,嵌套类型或在碱T类定义枚举可以明确发现即使对象有不止一个T类型的基类子对象。[...]

实际上,使用它的一个示例是标准,它指定标准容器的迭代器继承std::iterator模板,它只包含嵌套类型名称。继承的全部要点是将这些嵌套类型名称提供给迭代器。 (这个例子在下一个标准版本(C++ 17)中会过时,其中std::iterator被建议不再使用。)

2

X的范围是两个BB_,与B_的问题是,B_::X是模糊的,所以模板推演失败的truthy has_typedef离开假一个作为唯一的匹配。

+0

这是否意味着结构B会自动从结构A继承typedefed X?或者X是typedef以外的其他东西? –

+0

@FengWang只要typedef不是'private'或基类不是模板,是的。 – user657267