2016-05-13 5 views
16

私は 'typedef'が自動的に継承されないと信じていました。しかし、以下のコードスナップは、何か異なることを示唆しています。C++クラスで自動的に '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'です。 私の見解では、 'has_typedef_X<B>::value'は '真'を示しているので、構造体BではXはtypedefされています。

誰でもこの問題を説明したり、私を修正したりできますか?

オンライン版がhttp://melpon.org/wandbox/permlink/iwZ6eZ3PoBPgyFBjで利用可能である

+0

'T :: X'は' B_'であいまいです。リンクが壊れているようです –

+0

@PiotrSkotnickiありがとうございます。 URLを更新しました。私の問題は構造体Bです。私はそこに型定義されたXがないと信じていました。 –

+2

* "私は 'typedef'が自動的に継承されないと信じていました。*まあ、間違っています。 –

答えて

8

親のネストされた型名(メンバー型)は、アクセス指定子がprivateでない限り、派生クラスのスコープ内に表示され、アクセス可能です。 と同じ名前の複数のタイプがある場合、の基本クラスは、修飾されていない名前があいまいです。私はこれについて見つけ

最も関連性の高い標準の引用符は、以下のとおりです。

[class.nested.type] §1

タイプ名は他の名前とまったく同じスコープの規則に従います。 [...]

[class.member.lookup] §9

[注:オブジェクトがある場合でも、静的メンバー、ネストされたタイプまたは基本クラスTで定義された列挙を明確を見出すことができます[...]

実際に、これを使用する例は、標準コンテナのイテレータが012を継承することを指定する標準ですテンプレートには、ネストされた型名だけが含まれています。継承の全ポイントは、これらのネストされた型名をイテレータに渡すことです。 (この例は次の標準バージョン(C++ 17)では古くなり、std::iteratorはもう使用されないことが提案されています)。

2

Xを[URLを修正] BB_両方のスコープ内にある、B_の問題がB_::Xがあいまいであるということですので、テンプレート控除は偽を残しtruthy has_typedefのために失敗しました唯一の一致として1つ。

+0

これは、構造体Bが自動的に構造体Aから型定義されたXを継承することを意味しますか?あるいは、Xはtypedef以外のものですか? –

+0

@FengWang typedefが 'private'でないか基本クラスがテンプレートでない限り、そうです。 – user657267

2

2つの基本クラスで定義されているため、名前Xがあいまいであるため、B_のテンプレート控除がhas_typedefに失敗します。

typedefが継承されていないというあなたの信念は、基本クラスが考慮されていない非修飾名の参照の際に、C++の専門家から来ている可能性があります。 参照Propagating 'typedef' from based to derived class for 'template'

関連する問題