2016-12-15 2 views
5

clangとVC++でうまくコンパイルして警告を出すコードに対してgccの警告が表示されているので、gcc固有のものだと思います。これはコードです:-WSubobject-linkageの警告を修正するにはどうすればよいですか?

namespace myns { 
    using TokenList = std::vector<size_t>; 
    using RuleList = std::vector<size_t>; 
    using RulePathPair = std::pair<size_t, TokenList>; 
    using CandidatesCollection = struct { std::map<size_t, TokenList> tokens; std::set<RulePathPair> rules; }; 

    class A { 
    private: 
    CandidatesCollection _candidates; 
    }; 
} // namespace myns 

と警告がある:

警告: 'myns :: Aは' フィールド "mynsを:: A :: _候補者の持っているそのタイプなしリンケージ[を持っていません - Wsubobject-linkage]

これはどういう意味ですか、警告を取り除く方法は?

+2

質問と問題とは関係ありませんが、構造体の型名を定義するのに 'using'を使用しているのはなぜですか?構造名は型名そのものです。それが間違っていると言っているわけではなく、ちょうどそれが奇妙です。 :) –

+0

私は同じ考えをしていましたが、そこにパターンを残したかったのです。私は他のこのような定義をいくつか持っており、この表現のようです。 –

+0

古いC型typedef構造体のパターンを思い出しました – RyanP

答えて

1

私はここでコンパイラが間違っているかもしれないと信じています:CandidatesCollectionによって参照されるタイプは、実際に外部リンケージを持つべきです。それは

の名前である場合

[basic.link]/4 ...上記内部結合を与えられていない名前を有する名前空間の範囲は、囲んでいる名前空間と同じリンケージを有しています。 ..

(4.3) - という名前のクラス(項9)、またはクラスが連結目的のためtypedef名前(7.1.3)を有しているtypedef宣言で定義された名前のクラス。 ...


[dcl.typedef]/9typedef宣言は、名前のクラス(または列挙型)を定義している場合、そのクラスタイプであると宣言で宣言された第一のtypedef名(または列挙型のみ)(3.5)のクラス型(または列挙型)を示すために使用されます。 [例:

typedef struct { } *ps, S; // S is the class name for linkage purposes 

末端例] CandidatesCollection

typedef struct { ... } CandidatesCollection; 

と定義した場合にこのよう

、これら2つの通路は、それを明確にすることを作るCandidatesCollectionによって指定されたクラス喜んで外部のつながりを持っています。

そして

[dcl.typedef]/2のtypedef名があるともエイリアス宣言によって導入することができます。 usingキーワードに続く識別子は、のtypedef-nameとなり、識別子の属性指定子seqは、識別子のtypedef-nameに従います。それはtypedef指定子によって導入されたのと同じセマンティクスのを持っています。

強調鉱山。これは、usingによって導入された名前が、無名のクラスに ""という同等の宣言と同様に "リンケージ目的の名前"を与え、クラスが外部リンケージを持つことを保証することを示唆しています。

+0

うーん、面白い考え。私の心には来なかったが、ここで間違っている可能性がある。明確化のためにありがとう。ですから、唯一の解決策は '使用する 'ことではないようです。 –

関連する問題