C++ 模板专门化与编译器优化

C++ 模板专门化与编译器优化,c++,templates,C++,Templates,我有一个带有布尔模板参数的类 template<bool b> class Foo { void doFoo(); }; 对我来说,这似乎效率低下,因为每次调用函数时都必须执行if,尽管编译时应该知道正确的分支。我可以通过模板专门化解决此问题: 选项2 template<> void Foo<true>::doFoo() { cout << "hello"; } template<> void Foo<false>::

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

template<bool b>
class Foo {
  void doFoo();
};
对我来说,这似乎效率低下,因为每次调用函数时都必须执行
if
,尽管编译时应该知道正确的分支。我可以通过模板专门化解决此问题:

选项2

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

template void Foo::doFoo(){cout编译器可能会优化分支,因为在编译时知道什么是
b
。但这并不能保证,唯一确定的方法是检查程序集

如果您可以使用C++17,那么您就可以使用它,这保证了只存在一个分支

这在我看来效率很低,因为每次调用函数时我都必须执行if


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


在C++17中,您可以使用,未执行的分支将在编译时被丢弃。

这很酷,谢谢,我没有听说过。我希望我可以使用它:)如果带有任何优化标志的编译器没有优化分支,我会提交一个bug。:@Rakete1111。我想这意味着我们需要向MSV提交一个bug报告,因为它是唯一的一个在编译两个分支而不进行优化的“big 3”中:需要注意的是,这显然是在发布模式下优化的:请注意,如果在
if(b)
分支执行的操作在
!b
时格式不正确,则需要使用
if constepr(b)
或将其放入模板专门化,以防止编译器在
!b
时尝试编译它。如果这不是一个问题(例如,在您的示例中),我个人会坚持使用
If(b)
以保持清晰,或者如果我是在一个只使用C++17的世界中,则使用
If constexpr(b)
。我相信优化器会在这里做正确的事情。(其他人的回答和评论提供了实证证据,证明主流优化器确实值得信任。)这并不像另一个答案那么优雅,但据我所知,它并没有错。+1。@Bathsheba你说的“没有那么优雅”是什么意思?它(几乎)同样的答案。即使我认为内森的答案看起来更好,但它们如此相似,我不会花任何时间润色我的散文。
template<> void Foo<true>::doFoo() { cout << "hello"; }
template<> void Foo<false>::doFoo() { cout << "goodbye"; }