2

问题: 如何在编译时使用函数初始化非常量变量,同时仍然启用对所述函数的运行时调用?

详细信息:我正在使用 C++20,并且我有以下代码:

template<typename T>
constexpr auto diag(auto&&.. vals) {...}
// ...
constexpr auto M = diag<double>(1,2,3);

A 预期,上述代码编译,diag 在编译时执行,M 为常量。如果我将呼叫线路更改为

auto M = diag<double>(1,2,3);

代码再次编译,但这次 diag 在运行时执行,并且 M 不是常量。

我想将以上两者结合起来:在编译​​时执行 diag,但保持 M 可变;基本上是在编译时用一些复杂的东西初始化一个非常量变量,比如 diag 的返回值。

方法:我将代码更改为

template<typename T>
consteval auto diag(auto&&.. vals) {...}
// ...
auto M = diag<double>(1,2,3);

这一次,M 是非常量的,而 diag 是在编译时执行的,所以我的目标有效地实现了。我的问题是:consteval必须在编译时执行,所以如果我想在运行时代码的其他地方使用 diag,我将不得不编写另一个函数。

这导致了一个问题: 如何在编译时使用函数初始化非常量变量,同时仍然启用对所述函数的运行时调用?

注意: 在上面的示例代码中,diag 创建了一个具有给定条目的对角矩阵。我希望代码等效于

Matrix<double, 3, 3> M = { {1.0,0.0,0.0}, {0.0,2.0,0.0}, {0.0,0.0,3.0}};

这里,M 不是一个常数,而是从一个常数的、编译时确定的对角矩阵分配的。

4

1 回答 1

4

您可以使用中间constexpr变量:

constexpr auto MInit = diag<double>(1,2,3);
auto M = MInit;

您可以将其包装在 lambda 中:

auto M = [](){ constexpr auto MInit = diag<double>(1,2,3); return MInit; }();
于 2021-01-18T13:25:34.943 回答