在 msvc 的 constexpr 上下文中未调用构造函数体

问题描述 投票:0回答:1

我正在尝试将初始值设定项列表传递给结构的构造函数,其参数为

std::vector
,但我在 Visual Studio Community 中得到了意外的结果。这是重现问题的代码:

#include <vector>
#include <iostream>

using namespace std;

struct ST
{
    std::size_t size1;
    std::size_t size2;

    constexpr ST(std::vector<int> production) : size1(production.size())
    {
        size2 = production.size();
    }
};

static constexpr auto get_ST()
{
    return ST({ 1, 2, 3 });
}

int main()
{
    auto par = get_ST();
    std::cout << par.size1 << " " << par.size2 << std::endl;

    constexpr auto par2 = get_ST();
    std::cout << par2.size1 << " " << par2.size2 << std::endl;
}

在 Visual Studio Community 上,输出为:

3 3
3 0

gcc
中,我得到以下输出(https://godbolt.org/z/reqqdcEEh):

3 3
3 3

从输出中可以清楚地看出,当在 constexpr 上下文中计算结果时,MSVC 没有调用构造函数的主体。有谁知道这是否符合标准 C++ 或 MSVC 中的错误?

c++ visual-c++ g++ constexpr initializer-list
1个回答
0
投票

是的,这是 MSVC 中的一个错误 - 有趣的是,这是一个回归;这在 MSVC 19.28 (VS 16.9) 下有效,这是第一个支持 constexpr 析构函数的版本,但在更高版本中不起作用。

简化版是:

struct V {
    int z = 1;
    constexpr ~V() { z = 2; }
};
struct S {
    int i, j;
    constexpr S(V v) : i(v.z) {
        j = v.z;
    }
};
int main() {
    constexpr S s{V{}};
    return s.i * 10 + s.j;
}

一种解决方法是通过 const 引用或右值引用(或两者)获取构造函数参数;希望这对你有用。

我已在 https://developercommunity.visualstudio.com/t/Premature-constexpr-destruction-of-by-va/10547472 向 Microsoft 报告了此问题,以便您可以在那里跟踪问题。

© www.soinside.com 2019 - 2024. All rights reserved.