2013-05-15 100 views
14

noexcept修飾符可以應用於lambda表達式嗎?如果是這樣,怎麼樣?使用noexcept作爲lambda修飾符或參數約束

可以將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總是noexcept,這意味着如果你使用noexcept回調,這只是調用。

回答

16

能否noexcept改性劑被施加到一個lambda表達式?如果是這樣,怎麼樣?

括號後面添加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:sorry,unimplemented: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

不錯的嘗試,但不工作的時候通過免費功能,在鏗鏘3.5 f_async。 –

+0

http://rextester.com/RDIX55455 –

4

關於第一個問題:

能否noexcept改性劑被施加到一個lambda表達式?如果是這樣,怎麼樣?

是,只需添加例外規格參數列表後:

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

每款C++ 11標準的5.1.2/5:

的閉合類型一個lambda表達式有一個公共內聯函數調用操作符(13.5.4),其參數 和返回類型分別由lambda表達式的參數聲明子句和尾隨返回類型描述。當且僅當lambda表達式的 參數聲明子句沒有跟隨可變時,此函數調用運算符被聲明爲const(9.3.1)。它既不虛擬,也不宣佈爲 易變。默認參數(8.3.6)不應在lambda聲明的parameter-declaration-clause中指定。 在lambda表達式上指定的任何異常規範適用於相應的函數 調用運算符。 lambda聲明符中的attribute-specifier-seq屬於相應的函數調用運算符的類型。 [注意:lambda表達式中引用的名稱在 中的lambda表達式出現的上下文中查找。末端音符]