Flá*_*bôa 7 c++ virtual-functions constexpr c++11 c++14
前几天我正在阅读C++文档,并注意到虽然文字类型不能有虚拟成员,但这并不妨碍它们实现虚拟成员.或者至少这是我所理解的.
这是我一直在玩的一些代码:
#include <cassert>
// Some forward declarations:
enum class literal_id;
struct literal_base;
struct literal_a;
struct literal_b;
// Now some definitions:
enum class literal_id {
a, b
};
struct literal_base {
virtual literal_id method() const noexcept = 0;
};
struct literal_a : public literal_base {
constexpr literal_id method() const noexcept final { return literal_id::a; }
constexpr operator literal_b() const noexcept;
};
struct literal_b : public literal_base {
constexpr literal_id method() const noexcept final { return literal_id::b; }
constexpr operator literal_a() const noexcept;
};
constexpr literal_a::operator literal_b() const noexcept { return literal_b(); }
constexpr literal_b::operator literal_a() const noexcept { return literal_a(); }
// Some test methods
literal_id process_literal_base(literal_base const& l) { return l.method(); }
constexpr literal_id process_literal_a(literal_a const& l) { return l.method(); }
constexpr literal_id process_literal_b(literal_b const& l) { return l.method(); }
// Some test variables
constexpr auto a = literal_a();
constexpr auto b = literal_b();
int main() {
// Compile-time tests, all ok
static_assert(process_literal_a(b) == literal_id::a, "");
static_assert(process_literal_b(a) == literal_id::b, "");
// Runtime tests, all ok
assert(process_literal_base(a) == literal_id::a);
assert(process_literal_base(b) == literal_id::b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
一些评论:
literal_base
带有隐式(因此是微不足道的)析构函数的基类,因为它的子类都不应该只有一个简单的析构函数 - 毕竟它们是文字类型.literal_base
具有method
用于测试的单个函数,但其目的是使其具有所需数量的纯虚函数(非虚函数最终函数也有效).method
子类,也会标记子类中的替代.这只是为了使编译器静音,因为这些类应该是leaf(在它们的继承树中)或没有覆盖的函数.(所有这些都与pre-C++ 11未定义的行为语义有关,用于虚函数的最终实现,当说明符尚不存在时.)final
virtual
final
process_*
创建这些函数是为了帮助在编译和运行时声明实现的正确性....可能具有以下所有属性的cv限定类类型:
- (1)有一个简单的析构函数.[[他们有(
literal_base
我的意思是子类)]]- (2)是
- (2.1)聚合类型,[[不适用]]
- (2.2)一个至少有一个constexpr(可能是模板)构造函数的类型,它不是一个复制或移动构造函数,[[它有,但只是因为没有一个类有一个显式的构造函数; 但它很容易实现]]
- (2.3)闭包类型(自C++ 17起)[[不适用]]
- (3)对于工会,至少有一个非静态数据成员属于非易失性文字类型,[[不适用]]
- (4)对于非联合,所有非静态数据成员和基类都是非易失性文字类型.(因为C++ 17)[[
volatile
在示例中没有,并且都不应该volatile
在实际应用程序中使用; 另外,literal_base
子类应该是文字类型,因此必须(并且可以)应用此规则]]- (5)所有非静态数据成员和基类都是非易失性文字类型.[[基本上如[4]]]
现在有一些constexpr函数的定义:
- 它不能是虚[[没有子类有虚函数; 所有这些都是最终的,因此他们的位置是已知的,无需例如vtable]]
- (......)
我是否正确地承担这一切?有什么关于我忽略的规格吗?
Bar*_*rry 10
[dcl.constexpr]中的规则非常明确:
constexpr
功能的定义应满足以下要求:
- 不应是虚拟的(10.3);
literal_a::method
并且literal_b::method
都是virtual
因为他们每个都覆盖literal_base::method
,这是virtual
.因此,它们不可能是constexpr.
它们无关紧要final
.该计划格式不正确.
这是一个文本类型允许有一个真正的virtual
成员函数虽然.
归档时间: |
|
查看次数: |
1072 次 |
最近记录: |