模板专业化与编译器优化

时间:2018-05-21 13:19:51

标签: c++ templates

我有一个带有布尔模板参数的类。

template<bool b>
class Foo {
  void doFoo();
};

我希望doFoo根据b的价值做不同的事情。

天真地我可以写

选项1

template<bool b> void Foo<b>::doFoo() {
  if (b) cout << "hello";
  else cout << "goodbye";
}

这对我来说似乎效率低下,因为每次调用函数时我都必须执行if,尽管在编译时应该知道正确的分支。我可以通过模板专业化解决这个问题:

选项2

template<> void Foo<true>::doFoo() { cout << "hello"; }
template<> void Foo<false>::doFoo() { cout << "goodbye"; }

这样我在运行时就没有执行任何条件。这个解决方案有点复杂(特别是因为在我的实际代码中,类有几个模板参数,你不能部分专门化函数,所以我需要将函数包装在一个类中)。

我的问题是,编译器是否足够聪明,知道不执行条件选项1,因为它总是以相同的方式执行,还是需要编写特化?如果编译器足够智能,我很乐意知道这是依赖于编译器还是我可以依赖的语言特性?

2 个答案:

答案 0 :(得分:20)

编译器可能会优化分支,因为在编译时已知 public VisaCard (double V_Balance, double V_interest, double V_serviceCharge, double V_limit) { //There is a hidden super(); call here creditCard_Bal = V_Balance; //dose this make the VisaCard class the super? //end constructor } 是什么。但这并不能保证,唯一可以确定的方法是检查装配。

如果您可以使用C ++ 17,则可以使用documentation并保证只存在一个分支。

答案 1 :(得分:5)

  

这对我来说似乎效率低下,因为每次调用函数时都必须执行if

编译器可能会对此进行优化 - 但标准并不保证。确切地说,您应该查看您关心的编译器的输出(使用您计划使用的编译选项):例如。 clang在链接的example中没有分支(未优化的版本有很多函数调用样板但没有分支)。

在C ++ 17中,您可以使用if constexpr,并且在编译时将丢弃未采用的分支。