我可以写一个类似于简化函数模板的catch子句吗?
Can I write a catch clause similar to abbreviated function templates?
在程序的顶部,我有一个异常处理程序。
它看起来像这样:
try{
//majority of program
}
catch(...){
Handle_All_Exceptions();
}
void Handle_All_Exceptions(){
try{throw;}
catch(TypeA const& e){Handle(e) ;}
catch(TypeB const& e){Handle(e) ;}
catch(TypeC const& e){Handle(e) ;}
catch(TypeD const& e){Handle(e) ;}
catch(...) {Handle_Unknown();}
}
void Handle(TypeA const& e){
//...
}
void Handle(TypeB const& e){
//...
}
void Handle(TypeC const& e){
//...
}
void Handle(TypeD const& e){
//...
}
void Handle_Unknown(){
//...
}
当我获得越来越多的异常类型时,
我想采用一种更通用的方法。
如何将泛型编程应用于 Handle_All_Exceptions
函数?
像这样的东西在新版本的c++中可能吗?
catch(auto e){Handle(e)};
catch(...){Handle_Unknown();}
如果不对语言及其异常系统进行重大更改,这是不可能的。虽然catch子句处理程序和函数参数在语法上看起来很相似,但它们的工作方式却大不相同。考虑:
struct up {};
struct down { constexpr down(up) noexcept {} };
void func(down const&) {}
void except()
{
try {
throw up {};
} catch(down const&) {}
}
int main()
{
func(up {}); // fine
except(); // exception `up` escapes
}
Coliru
换句话说,down const&
参数将接受可转换为到down
的任何,而down const&
处理程序将绑定到类型为down
的异常对象或从down
中明确公开派生的类型。
这里最大的区别是形式"可转换为"的关系可以有多种形式。在我们的示例中,我们使用了转换构造函数,但是我们可以在up
内部使用转换操作符。而'is(公开的,明确的)派生自'只能以一种直接的方式被选中,并且只能在程序范围内的一个位置:定义派生类型的地方。当我们考虑单独编译时,这一点很重要。考虑下面的程序:
// a.cpp
// defined in b.cpp
void throws() noexcept(false);
template<typename X>
concept bool Fooable = requires(X x) { x.foo(); }
int main()
{
try {
throws();
// imaginary syntax for catching models of a concept
} catch(Fooable const&) {}
}
// b.cpp
// defined in c.cpp
struct other;
struct model {
void foo() {}
other* foo(int) { return nullptr; }
void bar() {}
};
void throws() noexcept(false)
{ throw model {}; }
// c.cpp omitted
当编译b.cpp
时,编译器无法知道a.cpp
会问"你抛出的对象是否能够执行x.foo()
?"它是否应该悲观地记录这一事实(以同样的方式,在当前的规则下,"来自于"的关系,如果有的话,被记录在某个地方)?它是否还应该记录model
能够执行x.bar()
的事实,即使整个程序不需要它?如果Fooable
代替x.foo(0)->baz()
测试呢?如果定义other
使表达式有意义,那么在哪里,何时以及如何记录?请注意model
和other
是如何分别定义的,并且每个都不了解对方(太多)。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 单行函数模板 c++ 的内联性保证
- C++函数模板需要 &for 数组参数
- 我可以写一个类似于简化函数模板的catch子句吗?
- 通过模板元编程用try包装任意函数调用.catch块在现代c++中