使用constexpr或struct进行元编程
Metaprogramming with constexpr or struct
我们刚刚开始学习c++ 11中的模板元编程。作为练习,我们编写了一个程序,输出int值的二进制表示形式。我们想出了两种可能的实现方法。第一个方法使用枚举值的递归,而第二个方法使用constexpr函数。
我们的期望是两个实现的结果是相同大小的可执行文件。但是,第一个实现产生9064字节,而第二个实现产生9096字节。我们不介意字节的微小差异,但不明白是什么导致了差异。
我们在没有优化标志的GCC 4.8.2中编译了这个程序,但是,使用-O2标志得到了相同的结果。
#include <iostream>
using namespace std;
template <int val>
struct Bin
{
enum { value = 10 * Bin<(val >> 1)>::value + (val & 1) };
};
template <>
struct Bin<0>
{
enum { value = 0 };
};
constexpr int bin(int val)
{
return val == 0 ? 0 : (10 * bin(val >> 1) + (val & 1));
}
int main()
{
// Option 1
cout << Bin<5>::value << 'n'
<< Bin<27>::value << 'n';
// Option 2
cout << bin(5) << 'n'
<< bin(27) << 'n';
}
constexpr
函数可以在编译时求值。他们不需要这样做。
对于你提供的代码,编译器确实没有这样做,bin
在运行时被调用;这意味着不能将函数从程序集中抛出。通过显式要求值为constexpr
并带有
constexpr auto i = bin(5), j = bin(27);
对bin
的调用在编译时完成,如下所示。
cout << bin(5) << 'n'
<< bin(27) << 'n';
发出的相关代码是
movl $5, %edi # Parameter
callq bin(int) # Here's the call to bin
movl std::cout, %edi
movl %eax, %esi
callq std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
[...]
movl $27, %edi # parameter
callq bin(int) # call to bin
movq %rbx, %rdi
movl %eax, %esi
callq std::basic_ostream<char, std::char_traits<char> >::operator<<(int)
当省略调用时,两个版本的大小相同。
相关文章:
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- C++Union/Struct位域的实现和可移植性
- 模板元编程:如何将参数包组合成新的参数包
- 如何在c++中定义以struct为数据成员的类中的构造函数
- Qt Q串行端口未编程设备未关闭
- 模板元编程 - 尝试实现维度分析
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- 我是编程新手
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- C++编程从外部文本文件定义数组大小
- 了解算法的性能差异(如果以不同的编程语言实现)
- 使用 Gtkmm 以编程方式选择 Gtk::TextView 中的文本
- 如何将可变参数模板转换为多个单个模板?(C++竞争编程调试模板)
- 错误:"Left of getValue must have class/struct/union"
- 在 SVM-Struct 中未定义对 sqrt 的引用(已使用 -lm)
- 在模板元编程中使用"struct xxx<>::val"导致错误
- 使用constexpr或struct进行元编程