C++ 虚constexpr协变返回类型

C++ 虚constexpr协变返回类型,c++,covariance,constexpr,c++20,C++,Covariance,Constexpr,C++20,据我所知,C++20取消了在constexpr上下文中使用虚拟函数的限制。改变本身很简单,不应是虚拟的词语被删除。这样做的理由似乎是,任何事物的动态类型都必须是已知的,因此允许它的成本几乎为零 引起我兴趣的是关于协方差的讨论。本文最后给出了一个例子: 根据我的理解,decltyper2.f很可能是X2常量,而不是X1常量。毕竟,如果动态类型是完全已知的,那么这不是最简单的实现吗 因此,在上面的示例中,我应该期望编译: constexpr decltype(r2.f()) zz = &x1

据我所知,C++20取消了在constexpr上下文中使用虚拟函数的限制。改变本身很简单,不应是虚拟的词语被删除。这样做的理由似乎是,任何事物的动态类型都必须是已知的,因此允许它的成本几乎为零

引起我兴趣的是关于协方差的讨论。本文最后给出了一个例子:

根据我的理解,decltyper2.f很可能是X2常量,而不是X1常量。毕竟,如果动态类型是完全已知的,那么这不是最简单的实现吗

因此,在上面的示例中,我应该期望编译:

constexpr decltype(r2.f()) zz = &x1;
FWIW编译器的版本可以在线获得,这不是我预期的。我这样问是因为如果这真的像我预期的那样工作,那么它将允许在编译时使用类型擦除风格的技术玩一些非常时髦的游戏

毕竟,如果动态类型是完全已知的,那么这不是最简单的实现吗

只是因为编译时调用代码并不意味着C++的正常规则会被暂停。如果表达式的类型在非编译时代码中是一种类型,那么如果该代码在编译时运行,则它将是相同的

在运行时,无论是否在编译时执行,运行时环境都知道对象的所有指针/引用的动态类型。毕竟,如果不这样做,dynamic_cast将无法工作。但这并没有改变这样一个事实,即调用基类函数将返回基类函数所表示的返回,而不管您碰巧传递的动态类型是什么

FWIW在线提供的编译器版本似乎接受了它,这不是我所预期的

之所以接受它,是因为&x1的类型为x1*,而decltype表达式的类型为x1*。所以你只是在复制一个X1*

毕竟,如果动态类型是完全已知的,那么这不是最简单的实现吗

只是因为编译时调用代码并不意味着C++的正常规则会被暂停。如果表达式的类型在非编译时代码中是一种类型,那么如果该代码在编译时运行,则它将是相同的

在运行时,无论是否在编译时执行,运行时环境都知道对象的所有指针/引用的动态类型。毕竟,如果不这样做,dynamic_cast将无法工作。但这并没有改变这样一个事实,即调用基类函数将返回基类函数所表示的返回,而不管您碰巧传递的动态类型是什么

FWIW在线提供的编译器版本似乎接受了它,这不是我所预期的


之所以接受它,是因为&x1的类型为x1*,而decltype表达式的类型为x1*。因此,您只是复制一个X1*

表达式的静态类型不会更改。表达式的静态类型不会更改。
constexpr decltype(r2.f()) zz = &x1;