【问题标题】:Virtual constexpr covariant return types虚拟 constexpr 协变返回类型
【发布时间】:2019-08-13 03:49:30
【问题描述】:

据我所知,this proposal C++20 放弃了在 constexpr 上下文中使用虚函数的限制。更改本身很简单,删除了“它不应是虚拟的”字样。这样做的理由似乎是无论如何都必须知道所有事物的动态类型,因此允许它的成本几乎为零。

引起我兴趣的是关于协方差的讨论。文末有一个例子:

struct X1
{
    constexpr virtual X1 const* f() const { return this; }
};

struct Y
{
    int m = 0;
};

struct X2: public Y, public X1
{
    constexpr virtual X2 const* f() const { return this; }
};

constexpr X1 x1;
static_assert( x1.f() == &x1 );

constexpr X2 x2;
constexpr X1 const& r2 = x2;
static_assert( r2.f() == &r2 );

根据我的阅读,decltype(r2.f()) 可能是 X2 const* 而不是 X1 const*。毕竟,如果动态类型是完全已知的,那不是最简单的实现吗?

所以在上面的例子中我应该期望它编译:

constexpr decltype(r2.f()) zz = &x1;

(FWIW 在线提供的编译器版本seem to accept it,这不是我所期望的。我问是因为如果这确实按我预期的方式工作,那么它将允许使用 type 玩一些非常时髦的游戏编译时的擦除样式技术)。

【问题讨论】:

  • 表达式的静态类型不会改变。

标签: c++ covariance constexpr c++20


【解决方案1】:

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

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

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

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

它被接受是因为&x1X1* 类型,而decltype 表达式是X1* 类型。所以你只是在复制X1*

【讨论】:

    猜你喜欢
    • 2017-10-21
    • 2011-07-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多