constexpr and virtual
constexpr and virtual
我一直在想为什么constexr
和virtual
是互斥的,有人补充道:
。。。constexpr完全是关于编译时的执行;如果我们在编译时执行函数,我们显然也知道它在编译时作用的数据类型,所以后期绑定显然不相关。
然而,即使在编译时,动态类型也可能与静态类型不相同,并且可能存在需要动态类型的情况:
class A {
public:
/* virtual */ constexpr int foo() {
return 1;
}
};
class B : public A {
public:
constexpr int foo() {
return 2;
}
};
constexpr int foo(A &a) {
// The static type is fixed here.
// What if we want to call B::foo() ?
return a.foo();
}
int main() {
B b;
constexpr int c = foo(b);
return 0;
}
也就是说,我的问题是
- 禁止两者结合的标准背后的(可能的)理由是什么
由于constexpr
是在C++11:中引入的,因此存在此限制
10.1.5
constexpr
说明符[dcl.constexpr]3 constexpr函数的定义应满足以下要求:
(3.1)-它不应是虚拟的
但您询问的是该限制的基本原理,而不是限制本身。
事实是,这可能只是一个疏忽。由于在常数表达式中,需要知道对象的动态类型,因此这种限制是不必要的,也是人为的:这就是Peter Dimov和Vassil Vassilev在P1064R0中所断言的,他们建议将其删除
事实上,目前的草案中已不存在这方面的措辞。
因为虚拟调用是通过运行时位于对象内存布局中的vtables/RTTI(运行时类型信息)解析的,所以在编译时"使用的对象句柄"后面的"true类型"是未知的。
在您的示例中:
constexpr int foo(A &a) {
// The static type is fixed here.
// What if we want to call B::foo() ?
return a.foo();
}
如果foo
成员函数是虚拟的,那么在编译时就无法执行该foo函数。如果函数永远不能在编译时执行,那么将其标记为constexpr
是没有意义的。因此,对constexpr
和virtual
都进行标记是没有意义的。
现在,从技术上讲,根据代码的复杂性,可以通过添加一个全新的系统(而不是RTTI)来解决多种情况,以解决编译时兼容的虚拟调用(例如,当所有内容都是constexpr
时,它会记住你在指针/引用中放入了什么类型的实例),但这现在根本不是问题。
如果您想要一个运行时间接(virtual
就是这样做的),那么也希望它在编译时执行是没有多大意义的。
第页。S: 很抱歉收到"编译时"answers"运行时"的垃圾邮件。
事实上,编译器有可能在编译时知道常量表达式的动态类型是什么。这是一种可能性,即优化器在编译时使用一些时间来破坏调用的机会。
但c++语言的发展也考虑到了在编译器中实现它的难度。如果不考虑这一点,那么c++标准将与c++编码的标准相距太远,因此它将是无用的。
也许,已经评估过,在常量表达式评估期间保持每个引用的静态类型的trac将过于昂贵,无法实现。这就是现实的伤害!
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- BoostPython and CMake
- 当我从下面的代码中删除关键字 virtual 时,它可以正常工作,否则会出现错误。在这里"virtual"字的意义是什么?
- OpenSSL BIO and SSL_read
- Gurobi GRBModel and GRBmodel in C++
- std::visit and std::variant usage
- SHBrowseForFolder with BIF_BROWSEFORCOMPUTER and SHGetPathFr
- Directx12 and keystrokes
- different between int **arr =new int [ n]; and int a[i][j]?
- C++ getenv and setenv
- Inference pytorch C++ with alexnet and cv::imread image
- Visual Studio 2019 C++ and std::filesystem
- 保证逻辑 AND 表达式中的函数调用
- constexpr and virtual
- virtual noexcept(true) errors: MinGW and gtkmm
- C++ ::std::enable_if and virtual