覆盖虚函数[[noreturn]]
Overriding a [[noreturn]] virtual function
[[noreturn]]
属性可以应用于不打算返回的函数。例如:
[[noreturn]] void will_throw() { throw std::runtime_error("bad, bad, bad ...."); }
但是我遇到了以下情况(不,这不是我设计的):
class B {
public:
virtual void f() { throw std::runtime_error(""); }
};
class D : public B {
void f() override { std::cout << "Hi" << std::endl; }
};
我真的想把属性[[noreturn]]
放在B::f()
声明上。但是我不清楚派生类中的重写会发生什么。从[[noreturn]]
函数成功返回会导致未定义的行为,如果重写也继承了该属性,我当然不希望出现这种情况。
问题:通过重写[[noreturn] virtual void B::f()
,我继承[[noreturn]]
属性吗?
我已经通读了c++ 14标准,但我在确定属性是否继承时遇到了麻烦。
我已经仔细检查了标准,没有迹象表明[[noreturn]]
或更一般的属性是通过重写函数"继承"的。
很难证明是否定的,标准实际上并没有声明这两种方式,但是,由于A::f()
和B::f()
仍然是不同的函数,唯一描述的行为是根据函数定义的,我认为你可以安全地将A::f()
标记为[[noreturn]]
。
话虽如此,我无法想象编译器随后可以执行什么有用的优化,给定动态分派。
在实践中,g++、clang和MSVC都不认为[[noreturn]]
属性是继承的
#include <iostream>
struct B {
public:
[[noreturn]] virtual void f() { std::cout << "Bn"; throw 0; }
};
struct D : public B {
void f() override { std::cout << "Dn"; }
};
int main()
{
try { B{}.f(); } catch(...) {}
D{}.f();
B* d = new D{};
d->f();
}
为所有三个编译器输出"B", "D"answers"D"
考虑你实际上在说什么:
class B
{
public:
[[noreturn]] virtual void f() { throw std::runtime_error(""); }
};
当然,人类读者,可能还有编译器,会解释这是一个"契约",即
"f()
不会返回,我保证"
这也应该适用于f()
的重写,否则你就违反了合同。
这个标准可能没有详细说明,但即使它有效,基于可读性,我也不建议使用。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将 [[noreturn]] 添加到主函数是否有意义
- 是否可以引入 noreturn noexcept 函数而不是调用 std::terminate
- 在可疑的情况下发出叮当警告:函数'foo'可以用属性"noreturn"声明吗?
- [[noreturn]] 函数指针
- [[noreturn]]函数怎么可能有返回类型
- 为什么要检查[[noreturn]]函数的返回类型?
- 在std::thread (c++11)中使用的函数可以有[[noreturn]]吗?
- 覆盖虚函数[[noreturn]]
- 错误:声明'noreturn'不应返回的函数