23

noexcept修飾子をラムダ式に適用できますか? もしそうなら、どのように?

noexcept関数の引数に制約を付けることができますか? たとえば、次のコードのように、コールバック関数がnoexcept?である必要があることを意味します。

//probably not valid code - I'm just trying to express the idea
void f_async(std::function<void (int) noexcept> callback) noexcept
{
    ...
}

これは次のコードでほぼ達成できますが、上記の代替のようなものを使用する方法があるかどうか疑問に思っています。

void f_async(std::function<void (int)> callback)
    noexcept(callback(std::declval<int>()))
{
    ...
}

もちろん、ここでの問題は、コールバックが次の場合に発生するf_async可能性があることです-常により強力なステートメントを作成したい、つまり、コールバックを使用する場合にのみ呼び出し可能です。noexcept(false)noexcept(false)f_async noexceptnoexcept

4

2 に答える 2

29

noexcept修飾子をラムダ式に適用できますか? もしそうなら、どのように?

noexcept括弧の後に追加:

[](Args args) noexcept { ... }

noexcept関数の引数に制約を付けることができますか?

はい、enable_if を使用します。

template <typename F>
auto f_async(const F& func) noexcept 
        -> typename std::enable_if<noexcept(func(0))>::type {
    func(0);
}

int main() {
    f_async([](int x) noexcept {});
    f_async([](int x) {}); // <- this line won't compile
}

ただしnoexcept、このメソッドはまだ式をマングルできないため、g++ 4.7 では直接動作しません (clang++ 3.2 では動作します) 。

3.cpp:5:6: 申し訳ありませんが、実装されていません: noexcept_expr をマングリングしています

ラッパー構造体を使用して回避できます。

template <typename F, typename... Args>
struct EnableIfNoexcept 
        : std::enable_if<noexcept(std::declval<F>()(std::declval<Args>()...))> {};

template <typename F>
auto f_async(const F& func) noexcept -> typename EnableIfNoexcept<F, int>::type {
    func(0);
}
于 2013-05-15T17:16:33.637 に答える
7

最初の質問に関して:

ラムダ式に noexcept 修飾子を適用できますか? もしそうなら、どのように?

はい、パラメーター リストの後に例外仕様を追加するだけです。

[] (int i) noexcept { return i * 1; };
//         ^^^^^^^^

C++11 標準のパラグラフ 5.1.2/5 によると:

ラムダ式のクロージャー型には、パブリック インライン関数呼び出し演算子 (13.5.4) があり、そのパラメーターと戻り値の型は、ラムダ式の parameter-declaration-clause と Trailingreturn-type によってそれぞれ記述されます。この関数呼び出し演算子は、ラムダ式の parameter-declaration-clause の後に mutable がない場合に限り、const (9.3.1) と宣言されます。仮想でもなく、宣言された揮発性でもありません。既定の引数 (8.3.6) は、ラムダ宣言子の parameter-declaration-clause で指定してはなりません。 ラムダ式で指定された例外仕様は、対応する関数呼び出し演算子に適用されます. ラムダ宣言子の属性指定子 seq は、対応する関数呼び出し演算子の型に関係します。[ 注: ラムダ宣言子で参照される名前は、ラムダ式が表示されるコンテキストで検索されます。—終わりのメモ]

于 2013-05-15T17:16:10.187 に答える