2013-05-15 7 views
14

noexcept修飾子をラムダ式に適用できますか?もしそうなら、どうですか?ラムダ修飾子またはパラメータ制約として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>())) 
{ 
    ... 
} 

ここではもちろんの問題は、コールバックがnoexcept(false)ある場合f_asyncnoexcept(false)にできることである - 私はあなたがnoexceptコールバックを使用する場合にのみ呼び出し可能です意味、f_async常にnoexceptであることを強い声明を作りたいです。最初の質問に関しては

答えて

16

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 
} 

を、この方法は、グラムで直接作業することはできません++ 4.7を(それが打ち鳴らす++ 3.2で作業をして)、それはまだnoexcept式をマングルすることはできませんので:

3.cpp:5:6:申し訳ありませんが実装されていません:mangling 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); 
} 
+0

興味深い - 私は本当にこの前に 'のstd :: enable_if'を見ていません。期待しているようだ。 –

+1

clang 3.5でf_asyncにフリー関数を渡すとうまくいきますが、うまくいきません。 –

+0

http://rextester.com/RDIX55455 –

4

はnoexcept修飾子は、ラムダ式に適用することはできますか?もしそうなら、どうですか?

はい、ちょうどパラメータリストの後に例外指定を追加します。

閉鎖タイプのため:

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

段落C++ 11標準の5.1.2/5パーラムダ式はパブリックインライン関数呼び出し演算子(13.5.4)を持ち、パラメータ と戻り値の型はラムダ式のパラメータ宣言節とtrailingreturn- の型でそれぞれ記述されています。この関数呼び出し演算子は、ラムダ式の のparameter-declaration-clauseの後にmutableがない場合にのみconst(9.3.1)と宣言されます。これは仮想でも宣言されていない volatileです。デフォルトの引数(8.3.6)は、ラムダ宣言者のパラメータ宣言節に指定してはならない。 ラムダ式で指定された例外仕様は、対応する関数 呼び出しオペレータに適用されます。ラムダ宣言子のattribute-specifier-seqは、対応する 関数呼び出し演算子の型に対応しています。 [注意:ラムダ宣言子で参照される名前は、ラムダ式が現れる というコンテキストで参照されます。末端ノート]

関連する問題