c++ - 非类型模板参数可以实现哪些优化?

标签 c++ templates compiler-optimization non-type

我在cppreference.com找到了这个例子,这似乎是 StackOverflow 中使用的事实上的示例:

template<int N>
struct S {
    int a[N];
};

当然,非类型模板化比这个例子更有值(value)。此语法还支持哪些其他优化?为什么创建它?

我很好奇,因为我的代码依赖于已安装的单独库的版本。我在嵌入式环境中工作,因此优化很重要,但我也希望有可读的代码。话虽这么说,我想使用这种风格的模板来处理版本差异(下面的示例)。首先,我是否正确地思考了这一点?最重要它比使用 #ifdef 语句有好处还是缺点?

尝试1:

template<int VERSION = 500>
void print (char *s);

template<int VERSION>
void print (char *s) {
    std::cout << "ERROR! Unsupported version: " << VERSION << "!" << std::endl;
}

template<>
void print<500> (char *s) {
    // print using 500 syntax
}

template<>
void print<600> (char *s) {
    // print using 600 syntax
}

OR - 由于模板在编译时是不变的,编译器是否可以使用类似于以下的语法来考虑 if 语句死代码的其他分支:

尝试2:

template<int VERSION = 500>
void print (char *s) {
   if (VERSION == 500) {
       // print using 500 syntax
   } else if (VERSION == 600) {
       // print using 600 syntax
   } else {
       std::cout << "ERROR! Unsupported version: " << VERSION << "!" << std::endl;
   }
}

这两种尝试都会产生与此相当的输出吗?

void print (char *s) {
#if defined(500)
    // print using 500 syntax
#elif defined(600)
    // print using 600 syntax
#else
    std::cout << "ERROR! Unsupported version: " << VERSION << "!" << std::endl;
#endif
}

如果你看不出我对这一切有点困惑,就我而言,解释越深入越好。

最佳答案

编译器发现消除死代码很容易。在这种情况下,您有一个 if 链(仅)依赖于 template 参数的值或类型。所有分支都必须包含有效的代码,但在编译和优化时,死分支就会消失。

一个典型的例子是使用控制代码流细节的模板参数编写的每像素操作。主体可以充满分支,但编译后的输出却没有分支。

类似的技术可用于展开循环(例如扫描线循环)。必须小心理解可能导致的代码大小倍增:特别是如果您的编译器缺少 ICF(又名 comdat 折叠),例如 gold gcc 链接器和 msvc(以及其他)所具有的。

还可以完成更奇特的事情,例如手动跳转表。

您可以进行纯粹的编译时类型检查,而无需任何运行时行为,例如维度分析。或者区分 n 空间中的点和 vector 。

枚举可用于命名类型或开关。指向函数的指针以实现高效内联。指向数据的指针,以允许可模拟、可孤立或与实现分离的“全局”状态。指向字符串的指针,以允许代码中高效可读的名称。用于多种目的的整数值列表,例如解包元组的索引技巧。对静态数据的复杂操作,例如对多个索引中的数据进行编译时排序,或者使用复杂的不变量检查静态数据的完整性。

我确信我错过了一些。

关于c++ - 非类型模板参数可以实现哪些优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27435736/

相关文章:

Java编译优化和性能

c++ - 同一段代码,可以在xcode中编译,也可以在terminal中用g++、clang++编译,不能用gcc或clang编译。为什么?

c++ - 具有枚举方向/类型的冒泡排序结构数组

c++ - gcc是否将非常量表达式函数的内置函数视为常量表达式

c++ - 在模板中比较 == !=

c++ - 为 vector : template parameters not deducible in partial specialization 定义散列

c - C 编译器优化的基准

java - 低功耗蓝牙 Java Api 或 C/C++ 库

c++ - 如何使用可变参数模板实现折叠

编译器定义,将函数重定向到不同的名称