9

私が持っているとします:

class Foo
{
public:
   virtual ~Foo()=default;
};

デフォルトのデストラクタの例外仕様は何ですか? デフォルトのデストラクタは次と同等です:

   virtual ~Foo() {};
or
   virtual ~Foo() throw() {};
or
   virtual ~Foo() noexcept {};

C++11 標準のセクション 15.4 は、デストラクタの暗黙的な定義によって直接呼び出される関数の例外仕様に依存すると述べています。この場合、メンバーも基本クラスもないため、暗黙のデストラクタによって直接呼び出される関数はありません。これは標準のあいまいさ (または省略) ですか?

もちろん、暗黙的に throw() がある場合は、すべてのサブクラスが throw() でデストラクタを宣言する必要があるため、これは重要です。デストラクタで例外をスローするのは悪い考えだとは言わないでください。例外仕様がまったく使用されていない多くのレガシー コードを扱っています。

参考までに、私が試したとき:

class SubFoo : public Foo
{
public:
   virtual ~SubFoo();
};

GCC 4.4 でエラー (例外仕様の不一致) が発生しましたが (ただし、正しいコマンド ライン スイッチがなかった可能性があることは認めます)、「11」コンパイラを使用する XCode 4.3 では発生しませんでした。

4

2 に答える 2

4

同じ文の前半に戻る (§15.4/14):

...その暗黙的な例外指定は、f の暗黙的な定義によって直接呼び出される関数の例外指定によって T が許可されている場合にのみ、型 ID T を指定します;..."

したがって、~Foo関数を呼び出さない場合は、例外のスローを許可しない暗黙の宣言があります。

§15.4/3 によると:

次の場合、2 つの例外仕様は互換性があります。

  • フォームに関係なく、どちらも投げません (以下を参照)。

ここではそのため、宣言がthrow()orであるかどうかは実際には問題ではありません。どちらの場合でも、noexceptこの 2 つには互換性があります。

于 2012-05-24T04:49:39.413 に答える
2

標準化はC++11§8.4.2/2でうまく始まります、

関数が最初の宣言で明示的にデフォルト設定されている場合—
暗黙の宣言がそうである場合は暗黙的にconstexprと見なされます
—暗黙的に宣言されている場合と同じ例外仕様を持つと暗黙的に見なされます(15.4)、…

しかし、その後、C++11§15.4/14では、ロジックが急速に進化し、

暗黙的に宣言された特別なメンバー関数(第12節)には、例外仕様が必要です。が暗黙的に宣言されたデフォルトコンストラクタ、コピーコンストラクタ、ムーブコンストラクタ、デストラクタ、コピー割り当て演算子、またはムーブ代入演算子の場合、関数の例外仕様で直接許可されている場合に限りf、その暗黙の例外仕様でタイプIDが指定されます。の暗黙の定義によって呼び出されます。直接呼び出す関数がすべての例外を許可する場合はすべての例外を許可し、直接呼び出すすべての関数が例外を許可しない場合は例外を許可しないものとします。TTfff

標準の「許可」の意味では、例外仕様を介して明示的に許可することです。

f2つの関数を呼び出す場合、そのうちの1つはを指定して許可Tし、もう1つはすべての例外を許可します。次に、すべての例外をf指定T して許可する必要がありますが、これは不可能です。

したがって、これは間違いなく標準の欠陥のように見えます。

関連する欠陥レポート、http: //www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1351を見つけました。

しかし、このエリアはただの大混乱のようです。:-(

于 2012-05-24T05:01:35.757 に答える