编译器如何优化模板?

时间:2015-10-30 20:18:06

标签: c++ templates

编写这样的代码是否有意义?

template<bool X>
double foo(double x){
     return (X) ? moo(x) : bar(x);
}

我知道有更好的方法来实现这个例子,但是我想知道,如果一般认为编译器会识别死代码并将其实例化为

是安全的。
double foo<true>(double x){return moo(x);}
double foo<false>(double x){return bar(x);}

3 个答案:

答案 0 :(得分:1)

我指定了#34; noinline&#34;为了使它更明显,我通过cin而不是使用常量值来获得值,以确保编译器不会完全删除函数。 enter image description here

如你所见,两者都是&lt;真&gt;和&lt;假&gt;有自己的功能。

true => +0x1780
false => +0x1790

模板函数总是根据模板参数

拥有自己的函数

答案 1 :(得分:1)

这里要记住的是模板与C#等语言中的泛型等语言功能不同。

将模板视为可识别类型的高级预处理器是一种相当安全的简化。这是Template metaprogramming (TMP)背后的想法,它基本上是编译时编程。

就像扩展预处理器模板一样,结果会经历与普通逻辑相同的所有优化阶段。

以下是以与TMP更一致的样式重写逻辑的示例。这使用函数专业化。

template<bool X>
double foo(double x);

template<>
double foo<true>(double x)
{
    return moo(x);
}

template<>
double foo<false>(double x)
{
    return bar(x);
}

TMP实际上被发现是一个幸福的事故,几乎是STLBoost的面包和黄油。

它是turing complete所以你可以在编译时进行各种计算。

它被懒惰地评估,因此您可以通过将无效逻辑放在您不想使用的模板的特化中来实现自己的编译时断言。例如,如果我要评论foo<false>专业化并试图像foo<false>(1.0);那样使用它,编译器会抱怨,尽管它会对foo<true>(1.0);非常满意。

Here是另一个Stack Overflow帖子,用于演示此内容。

如果感兴趣,请进一步阅读:

  1. Modern C++ Design
  2. C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond
  3. Effective C++

答案 2 :(得分:0)

  

...一般来说,假设编译器会识别死机是安全的   代码并将其实例化为

double foo<true>(double x){return moo(x);}
double foo<false>(double x){return bar(x);}

从迂腐的角度来看,答案是 no 。真正发生的是你最终会得到两个看起来像这样的函数:

template <>
double foo<true>(double x) {
     return (true) ? moo(x) : bar(x);
}

template <>
double foo<false>(double x) {
     return (false) ? moo(x) : bar(x);
}

这些功能中的每一个都将通过相当明显的死代码消除优化进行优化。你最终会得到相同的结果,但是有一个中间步骤。

有一种不同的技术可以做你想要的,但有一些优点。您可以依赖C ++重载和一个名为std::integral_constant的帮助器类型,使其在条件表达式中100%无法编译。

double foo(double x, std::true_type) {
    return moo(x);
}

double foo(double x, std::false_type) {
    return bar(x);
}