【问题标题】:assign a templated variable at runtime在运行时分配模板化变量
【发布时间】:2020-12-20 03:17:34
【问题描述】:

到目前为止,我有一些代码运行良好,但有一个新的更改正在破坏它。寻找有关如何处理它的想法。我不是 C++ 模板专家,具有基本的工作知识。

namespace foo {
enum {
A1,
A2,
..
AN
};

constexpr int A = 
#if defined(SOME_DEFINE1)
A1,
#elif defined(SOME_DEFINE2)
A2,
...
#elif defined(SOME_DEFINEN)
AN
#endif
;

// Then I have some variables that depend on A
template<int> struct var1;
template<>struct var1<A1> { static constexpr auto value = v1; }
template<>struct var1<A2> { static constexpr auto value = v2; }
template<>struct var1<A3> { static constexpr auto value = v3; }

template<int> struct var2;
template<>struct var2<A1> { static constexpr auto value = x1; }
template<>struct var2<A2> { static constexpr auto value = x2; }
template<>struct var2<A3> { static constexpr auto value = x3; }
} // namespace foo

constexpr auto VAR1 = foo::var1<foo::A>::value;
constexpr auto VAR2 = foo::var2<foo::A>::value;

现在 VAR1 和 VAR2 在多个地方使用。我知道所有这些代码都将由编译器优化并且一切正常。

现在由于新的变化,我只能在运行时知道“A”的值,因此不能再声明为常量。 A 将由某处的全局变量的值确定。关于如何实现这一点的任何想法,所以我对我的代码进行了非常小的更改。

假设有一个 gVal 可以是 1,2 或 3,基于此我想将 A 设置为 A1、A2 或 A3,这会影响其他变量的值。非常感谢任何帮助。

【问题讨论】:

  • var1var2 不是变量,但您使用 = 符号定义它们,就好像它们是变量一样。您的代码无法编译。
  • 抱歉打错了。 var1、var2...等没有“=”符号
  • 你不能让模板是运行时的,它们是在编译时评估的。您的 VAR1 和 VAR2 是 constexpr,因此如果您更改代码,则必须检查 ALL 您的代码。
  • 本质上,如果A 是在运行时确定的,VAR1 等就不能再使用模板机制来确定——这是在编译时完成/评估的,所以不能推迟到运行时.我可能只是编写一个函数来将foo::A 的可能值映射到所需的结果。根据您的代码的许多其他细节(您没有显示),函数可能是constexpr - 这意味着,如果它传递了一个在编译时已知的常量,则可以在编译时对其进行评估.如果可能的话,您可以消除部分模板机制。

标签: c++ c++11 templates c++17 constexpr


【解决方案1】:

我能想到三种理智的方法。

  1. 一块一块地改写成constexpr函数,一路单元测试,保持旧版本不变。然后换成 constexpr 函数的运行时版本。

  2. 将您的程序(或程序的一部分)包装在一个以A 作为参数的大模板中。为每个有效的A 实例化这些模板之一。为此编写一个接口,用于选择要使用的大量模板实例中的哪一个。

  3. 将此视为用另一种语言重新实现代码。使用现有代码作为基础,但不要重用它。编译时 C++ 与运行时 C++ 不太相似。

在我看来:2 是最快的,3 需要最少的技能才能取得进步,1 需要的时间最长但最不可能引入新的回归。

【讨论】:

    猜你喜欢
    • 2012-11-08
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    相关资源
    最近更新 更多