这可能是一个非常明显的问题,但我希望在继续我的开发之前确定它。
我有一个模板化的类,如:
template<TypeA var1, TypeB var2>
class myClass
{
//Attributes
...
//Methods
...
void checkHit(vector<Real>* path, vector<bool>* active)
{
for(int i = 0; i < N; i++)
{
//Some process
bool hit = ((var1 == Up) || (var1 == Down));
}
//...
bool flag = ((var2 == Left) || (var2 == Right));
}
}
如果我创建和对象
myClass obj<Up, Right>(...);
执行方法时
obj.checkHit( ... );
程序会检查bool hit = ((var1 == Up)
和(var2 == Right)
吗?换句话说,编译器是否会丢弃与传递的模板参数无关的代码?我的意思是,编译后生成的代码是否类似于
template<TypeA var1, TypeB var2>
class myClass
{
//Attributes
...
//Methods
...
void checkHit(vector<Real>* path, vector<bool>* active)
{
for(int i = 0; i < N; i++)
{
//Some process
bool hit = ((var1 == Up)); //Like if I have never put "|| (var1 == Down));"
}
//...
bool flag = ((var2 == Right));
}
}
希望这个例子足够清楚,我只是简化了(很多)真正的代码,但它应该大致相当。如果不清楚只是告诉我,我会很乐意改进它。
答案 0 :(得分:1)
示例不够清楚,没有“与传递的模板参数无关的代码”,因为没有任何内容取决于hit
或flag
,所以一个不错的优化器将checkHit
变成一个完全空的函数!
编译器可以在编译时评估((var1 == TypeA::Up) || (var2 == TypeB::Down))
条件,并且一个不错的优化编译器会将该条件的结果传播到函数的其余部分,从而删除任何永远不会运行的死代码那个条件的价值。
另外,你真的想通过值传递这些参数吗?
void checkHit(vector<Real> path, vector<bool> active)
答案 1 :(得分:1)
我假设您的TypeA
和TypeB
是枚举或某种类/结构并定义了这些值?
在这种情况下,编译器不会在这里“抛弃”代码。您的条件检查以查看模板参数是什么,因此如果它们与条件中的内容不匹配,您最终会得到一个基本上会执行此操作的调用:
bool hit = (0 == 1 || 1 == 2);
根据您的优化设置,编译器可能会意识到这将始终为false并且只是将其设置为false(还假设您在函数中执行了一些有用的操作,因此编译器不会将其转换为noop)。 / p>
你也应该通过引用传递你的向量(或常量引用),我会避免使用vector<bool>
。
答案 2 :(得分:0)
程序不会丢弃代码的任何部分。模板类仅用于概括类的使用。选择typeA
和Type B
它们都将被视为代码中的Type A
和Type B
以及代码的其余部分将以不使用任何模板的正常方式执行