18

このコードは GCC4.7 ではコンパイルできません

struct A {};
void f(A);

struct B { B(std::tuple<A>); };
void f(B);

int main() {
  f(std::make_tuple(A()));
}

AGCC は空の基本クラスの最適化を利用するために派生するためです。ただし、それによりGCCが選択f(A)して不平を言います

エラー:'A'アクセスできないベースです'tuple<A>'

このエラーは C++ 標準によって許可されていますか、それとも単に libstdc++ のバグですか?

4

2 に答える 2

3

いいえと思います。

少なくとも:

§20.4.1 [tuple.general]

1/ [...] 2 つの引数を持つタプルのインスタンス化は、同じ 2 つの引数を持つペアのインスタンス化に似ています。20.3 を参照してください。

それでも:

#include <tuple>

struct A {};
void f(A);

struct B { B(std::tuple<A, A>); };
void f(B);

int main() {
  f(std::make_tuple(A(), A()));
}

次のエラーで失敗します:

Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:10:30: error: 'A' is an ambiguous base of 'std::tuple<A, A>'
source.cpp:4:6: error: initializing argument 1 of 'void f(A)'

そして、これが標準の意図であったかどうかは非常に疑わしい.

それでも、少なくとも言えることは、§20.4 はかなり簡潔だということです...

于 2012-12-16T16:07:04.880 に答える
2

第 17 条図書館の紹介:

17.5.2.3 プライベートメンバー [objects.within.classes]

1 - 条項 18 から 30 および付属書 D は、クラスの表現を指定しておらず、意図的にクラス メンバの指定を省略しています。実装は、条項 18 から 30 および附属書 D で指定されたメンバー関数のセマンティクスを実装するために必要に応じて、静的または非静的クラス メンバー、またはその両方を定義することができます。

これは、1.4 実装コンプライアンス [intro.compliance]によってサポートされています。

3 - クラスおよびクラス テンプレートの場合、ライブラリの Clauses は部分的な定義を指定します。プライベート メンバー (条項 11) は指定されていませんが、各実装は、ライブラリ条項の説明に従って定義を完了するためにそれらを提供する必要があります。

継承による指定されたセマンティクスの実装は、第 17 節のどこにも明示的に議論されていませんが、上記の 17.5.2.3 の第 3 段落を通じて暗黙的に許可されています。

3 - 実装では、同等の外部動作を提供する任意の手法を使用できます。

これは、たとえば、ノードベースの順序付けられた連想コンテナーが、継承によって実装の詳細 (最終的にはクラス メンバーを含む) を共有できる方法です。

の外部動作は、クラス メンバーとしてtuple持つA場合と直接継承する場合とで変更されるため、また、この動作の変更により、(単にクラスの を変更するのではなく) 適切な形式のプログラムが拒否されるためsizeof、libstdc++ は次の規則に違反しています。標準。

于 2012-12-17T10:45:08.753 に答える