问题描述
我有一些直到现在为止仍然有效的代码,但是有一个新的更改正在破坏它。寻找有关如何处理它的想法。我不是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,这会影响其他变量的值。任何帮助将不胜感激。
解决方法
我可以想到三种理智的方法。
-
一步一步地重写为constexpr函数,进行单元测试,并保持旧版本完整。然后交换到constexpr函数的运行时版本。
-
将程序(或程序片段)包装在一个以
A
作为参数的大模板中。为每个有效的A
实例化这些模板之一。为此编写一个接口,以选择要使用的大量模板实例中的哪个。 -
将此作为另一种语言的重新实现代码进行处理。以现有代码为基础,但不要重复使用。编译时C ++与运行时C ++不太相似。
我认为:2是最快的,3需要最少的技能才能取得进步,1花费的时间最长,但是引入新回归的可能性最小。