这是我试图用 C++ 做的事情。从我使用的外部库中,我有 3 个类:MyClass1
、MyClass2
和 MyClass3
,它们的公共(public)函数是相同的。我想在运行时开始时决定根据用户的硬件配置在我的代码的其余部分中使用哪一个。
为了更好地说明我的意思,让我举一个我知道行不通的例子。 如果可以在运行时有条件地定义typedef
,我想要实现的将如下所示:
const int x = GetX(); //where GetX() is any function that calculates the value of x
typedef std::conditional<x > 0, MyClass1,
std::conditional< x < 0, MyClass2,
MyClass3>::type>::type TheClass;
因此,在代码的其余部分中,我只会引用 TheClass
,这样无论它是否是别名 MyClass1
、 都无关紧要MyClass2
或 MyClass3
。
但是,上面的代码当然不起作用,因为当 x
从运行时开始执行的函数计算出其值时,std::conditional
会提示x 不是常量。这是有道理的,因为 typedef
无法在运行时定义。
所以,我的问题:有没有办法实现我想要做的事情(不是使用 typedef
因为我知道它不能在运行时定义)?请记住,MyClass1
、MyClass2
和 MyClass3
是由库外部提供的,因此我无法轻易更改它们。
最佳答案
我能看到的唯一解决方案是使用模板为您生成代码。模语法错误,你的 std::conditional
只要您将 x 转换为编译器已知的值,基于解决方案的解决方案就可以工作。诀窍是将所有使用 typedef 的代码包装在以整数作为模板参数的模板函数/类中,如下所示:
template <int x>
void myMain(){
using TheClass = typename std::conditional<x == 0, MyClass1, MyClass2>::type;
然后您要确保编译所有变体(在我的示例中为 0 和非零),为此您显式调用 myMain<0>()
比如说 myMain<1>()
,如:
if(x == 0){
myMain<0>();
}
else{
myMain<1>();
}
现在,您已将条件转换为在运行时评估的内容,但您已经编译了两种情况的代码,并且可以根据需要执行其中每个(或两个)。
这有一个缺点,就是将使用该类的任何内容都放入模板或由模板调用的内容中。除了"dispatch"点之外,我建议在类型上而不是整数上使用模板(请参阅示例中的函数 doSomethingWithClass
);这更好地表达了这样一个事实:您的代码可以与您要实例化它的所有类型一起使用。如果您想确保只能使用您感兴趣的三个类来实例化函数,则应该考虑使用 CRTP 模式(奇怪的重复模板参数)。
另一方面,这有一个优点(相对于基于多态性的其他答案):您可以使用堆栈而不是堆。
您可以找到一个工作示例 here .
希望有帮助。
关于c++ - 在运行时有条件地定义 3 个类中的哪一个将在其余 C++ 代码中使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40781984/