我正在尝试将初始值设定项列表传递给结构的构造函数,其参数为
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 中的错误?
是的,这是 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 报告了此问题,以便您可以在那里跟踪问题。