2013-05-15 98 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表达式出现的上下文中查找。末端音符]