Ada*_*nes 6 c++ member-initialization function-try-block
在具有多个成员的类的成员初始化期间,似乎希望能够捕获由任何特定成员初始化程序生成的异常,以包装在额外的上下文中以便重新抛出,但是函数 try 块的语法没有出现为了适应这一点。
#include <stdexcept>
#include <string>
#include <sstream>
using namespace std::literals::string_literals;
[[noreturn]]
int thrower() { throw std::runtime_error("unconditional throw"s); }
int nonThrower() { return 3; }
class C {
int x;
int y;
public:
C();
};
class XError : public std::runtime_error {
public:
XError(const std::string& what) : std::runtime_error((std::stringstream() << "xerror: "s << what).str()) {};
};
class YError : public std::runtime_error {
public:
YError(const std::string& what) : std::runtime_error((std::stringstream() << "yerror: "s << what).str()) {};
};
C::C() try:
x(nonThrower()),
y(thrower()) {}
catch(const std::exception& e) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
XError()在上面的简单示例中,在最后一行,如果异常发生在 的初始化中.x,并且YError()如果异常发生在 的初始化中,我非常希望能够抛出.y。
理想情况下我希望能够做类似的事情
// -std=c++3000
C::C():
try: x(nonThrower()) catch(const std::exception& e) { throw XError(e.what()); },
try: y(thrower()) catch(const std::exception& e) { throw YError(e.what()); } {}
Run Code Online (Sandbox Code Playgroud)
但似乎我唯一的选择是为每个初始化程序成员编写单独的函数,这些函数本身包装异常,然后在成员初始化程序中使用这些函数。考虑到成员初始化语法是多么可怕,这可能会读起来更好,但它不太紧凑,而且更非线性,这不太理想。为了完整性:
int makeX() {
try { return nonThrower(); }
catch(const std::exception& e) { throw XError(e.what()); }
}
int makeY() {
try { return thrower(); }
catch(const std::exception& e) { throw YError(e.what()); }
}
C::C():
x(makeX()),
y(makeY()) {}
Run Code Online (Sandbox Code Playgroud)
请原谅我的 C++ 中的任何反模式或错误。我对这门语言很陌生,而且不像你希望的那样聪明。
每个成员初始化器是否可以有一个函数尝试块?
不,那是不可能的。
侧边栏:看来您过度使用和/或过度思考异常。大多数人不会编写太多异常处理代码,因为大多数程序在大多数地方只要抛出异常就终止就可以了。当然,这条规则也有例外,但如果您是 C++ 新手并且对此很着迷,那么您可能应该重新审视您的方法,而不是让您的程序如此依赖于细粒度的异常处理。
这是不可能的,但如果你想走异常路线,你可以编写函数包装器:
template<typename Exn, typename T>
T catch_with(T (*fn)()) // or, std::function<T()> fn
{
try { return fn(); }
catch(const std::exception& e) { throw Exn(e.what()); }
}
C::C():
x(catch_with<XError>(nonThrower)),
y(catch_with<YError>(thrower) {}
Run Code Online (Sandbox Code Playgroud)