【发布时间】:2018-01-18 19:05:50
【问题描述】:
我正在尝试了解 noexcept 功能。 我知道这可能会造成混淆,但除此之外,如果可能的话,可以从调用函数中推断出 noexcept。
这是这种情况的一个无效示例,
void f(){}
void f() noexcept{} // not allowed in c++
void g(){f();} // should call f
void h() noexcept{f();} // should call f noexcept
int main(){
g();
h();
}
如果调用函数 (h) 中没有 try/catch 块,则编译器可以推断出有兴趣调用特定的 f。
此模式是否用于其他解决方法?
我能想象的都是这样的,但它不是很通用:
template<bool NE> void F() noexcept(NE);
template<>
void F<true>() noexcept(true){}
template<>
void F<false>() noexcept(false){}
void g(){F<noexcept(g)>();} // calls F<false>
void h() noexcept{F<noexcept(h)>();} // call F<true>
有些人可能想知道为什么这样做有意义。
我的逻辑是 C++ 允许对 const 进行重载,既是函数的参数,也是成员函数。
例如,const 成员函数更喜欢调用 const 成员重载。
我认为noexcept 函数调用noexcept“重载”是有意义的。特别是如果它们不是从 try/catch 块中调用的。
【问题讨论】:
-
使用 c++17,您可以使用
if constexpr,如:template<bool NE> void F() noexcept(NE) { if constexpr(NE) { ... } else { ... } }。不确定它对您的问题是否有用。 -
这种重载的用例是什么?无论
f正在做什么都不会失败,在这种情况下不需要noexcept(false)版本,或者它可能会失败,因此noexcept(true)版本需要某种方式来报告该失败,这通常意味着不同的签名。 -
"如果调用函数 (h) 中没有 try/catch 块,那么编译器可以推断出有人对调用特定 f 感兴趣。"大多数异常安全代码没有 try 块;它依赖于 RAII。它仍然想调用 noexcept(false) 版本。
-
如果你想要版本,一个通过返回值报告错误,另一个通过异常报告,看看
std::nothrow,以及它是如何使用的。 -
@Deduplicator,非常好。不知道
std::nothrow,这似乎是要遵循的成语。
标签: c++11 overloading overload-resolution noexcept c++17