2017-10-12 10 views
4

へのポインタメンバ関数を呼び出した後、このMWEが不自然見えるかもしれませんが、失敗static_assertはそれにもかかわらず、驚くべきことである失敗しますオペラのnoexceptの文脈では、 "これ"とは違った扱いがあるため、GCCではなくClangである。noexcept演算子は

+0

は、あなたの質問は何ですか? – aschepler

+0

の答えの一つは、あなたの質問に答えた場合、あなたはそれを受け入れることができます。場合どちらもあなたの質問に答えなかったのですが、私たちが答えを改善できるように理由を説明できますか? – Justin

+0

長い間遅れて申し訳ありません。私は答えに満足していませんでしたが、私は彼らが言い表されたように質問に答えるので、私は1つを受け入れるでしょう。しかし、私の場合、 "f"はライブラリのユーザが渡すテンプレートパラメータなので、関数型のnoexcept-nessを問い合わせて、メンバ関数へのポインタのnoexcept指定子を適切に宣言する必要があります。残念ながら、型エイリアスにnoexceptを追加しても、Fのエイリアスがテンプレート化されてコンパイルされないため、内部コンパイラエラーが発生します。私はこれについてClangのバグを投稿します。 – Jackie

答えて

7

static_assertには文字列引数がないので、C++ 17を使用しています。 C++ 17ではnoexceptが型システムの一部となりました。これが意味することは与えられたということです。

using F = void(C::*)(); 

このPMFはnoexceptではありません。それを呼び出すことは、メンバー関数noexcept(false)を呼び出すのと同じです。あなたはnoexceptとして機能タイプをマークする必要があります。

using F = void(C::*)() noexcept; 

変更は、あなたのコードがコンパイルできること:

#include <utility> 

struct C { 
    void f() noexcept { } 
    using F = void(C::*)() noexcept; 

    static constexpr F handler() noexcept { 
    return &C::f; 
    } 

    void g() noexcept(noexcept((this->*handler())())) { 
    } 
}; 

int main() { 
    static_assert(noexcept(std::declval<C>().g())); 
} 

On Godbolt

3

fnoexceptですが、それへのポインタではありません。したがって、gの定義では、this->*handler()noexceptではないPMFを返します(noexceptのMFのアドレスを返しても、(this->*handler())()と書くと、そうでない関数が呼び出されます) noexceptは、noexcept句のでfalseが返されます。

をライン5の最後にnoexceptを追加し、それが動作します。