GCC 4.8.4、4.9.3、5.3.0のすべてが(-std = C++ 11/1Y/14/1Z/17の任意の利用可能なオプションのために)std::exception
ためのテストに合格:std :: runtime_error noexceptのコピーコンストラクタとコピーの割り当てはありますか?
static_assert(std::is_nothrow_copy_constructible<std::exception>::value, "test exception");
static_assert(std::is_nothrow_copy_assignable <std::exception>::value, "test exception");
:
namespace std { class exception { public: exception() noexcept; exception(const exception&) noexcept; exception& operator=(const exception&) noexcept; virtual ~exception(); virtual const char* what() const noexcept; }; }
残念ながら、上記のコンパイラのすべては、以下のstatic_assert
秒で失敗:std::exception
はnoexcept特別会員(C++ 14 18.8.1)がいるので、大丈夫です
static_assert(std::is_nothrow_copy_constructible<std::runtime_error>::value, "test runtime_error");
static_assert(std::is_nothrow_copy_assignable <std::runtime_error>::value, "test runtime_error");
標準のみ19.2.6約std::runtime_error
次のものが含まれます。
namespace std { class runtime_error : public exception { public: explicit runtime_error(const string& what_arg); explicit runtime_error(const char* what_arg); }; }
をしかし、何も他の(暗黙のうちに特別に宣言)のメンバーでもストレージ実装のnoexcept
ネスについては述べられていませんwhat_arg
の要件。
標準(C++ 14)15.4/14で次の言葉:
継承コンストラクタ(12.9)と暗黙的に宣言された特別な メンバ関数(条項12)は例外仕様を有しています。 fが 継承コンストラクタまたは暗黙的に宣言されたデフォルトの コンストラクタ、コピーコンストラクタ、移動コンストラクタ、デストラクタ、コピー 代入演算子、または代入演算子を移動する場合、その暗黙的な 例外指定では、T fの暗黙の定義によって が直接呼び出された関数の例外仕様によって許可された です。 fが直接呼び出す関数がすべての例外を許可する場合はすべての例外を許可し、直接呼び出すすべての関数が例外を許可しない場合はfは 例外仕様noexcept(true)を持ちます。
そして18.8.1/2で次
クラス例外から派生した各標準ライブラリのクラスT は、公的にアクセス可能なコピーコンストラクタと行う公的 アクセスコピー代入演算子を持たなければなりません 例外で終了しないでください。
std::runtime_error
がwhat_arg
ストレージの実装を公開していませんので、我々はそれが(特別な)メンバーがnoexceptかないので、std::runtime_error
年代のnoexceptnessはコピーコンストラクタや代入メンバーが決定不能ですコピーだかどうかわかりません。私たちの唯一の賭けは18.8.1です。
質問1/a)std::runtime_error
のコピーコンストラクタまたはコピー割り当てをnoexcept(1,)と見なします。これは本当の/最先端の/ベストプラクティスですか?
質問1/b)標準でこれを明示する必要はありませんか? (18.8のように。2、Class bad_exception
)
質問1/c)上記のstatic_assertテストに失敗したGCCのバグですか?
質問2)上記の控除が間違っていると、std :: runtime_errorにnoexceptコピーコンストラクタ(およびコピー代入)があることを示す標準のセクションに誰かを指摘できますか? (それとも、そうでないと述べている。)
gcc 5.3.0は 'std :: runtime_error'のテストに合格していますか? [gcc 5.2.0がテストに合格したようです](http://melpon.org/wandbox/permlink/aHDNg8cs7ttnJlaW)。 – cpplearner
g ++ - 5(Ubuntu 5.3.0-3ubuntu1〜14.04)5.3.0 20151204で試してみましたが、失敗します。 –
GCC 5.3.0のインストールには、/usr/include/c++/5.3.0/stdexceptに次のような問題がある可能性があります。 #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS runtime_error(const runtime_error&)_GLIBCXX_ssss_USE_NOEXCEPT; runtime_error&operator =(const runtime_error&)_GLIBCXX_USE_NOEXCEPT; #endif しかし、エラーは出ませんでした。(私は_GLIBCXX_defineを変更しました) –