用C语言创建具有局部变量的类C++模板函数
Creating a C++ Template Like Functions With Local Variables in C
这里有一个谜。
假设我有以下C++函数:
template<uint8_t MASK>
uint8_t Foo(uint8_t val)
{
uint8_t step = 0;
uint8_t result = 0;
if(MASK & 0x01) {result |= (val & 0x01) >> step; ++step;}
if(MASK & 0x02) {result |= (val & 0x02) >> step; ++step;}
//...etc...
if(MASK & 0x80) {result |= (val & 0x80) >> step; ++step;}
return result;
}
当我这样实例化这个函数时(下面的所有值都只是示例值):
uint8_t someval = Foo<0xAA>(44);
编译器优化了Foo()中的if语句,因为它在编译时知道所述if()语句的结果是什么。
这很好,但在C中尝试这样做是有问题的,因为创建了局部变量step。
如果没有步骤,你可以像这样做一个大的#定义:
#define Foo(MASK, val) (
((MASK & 0x01) ? (val & 0x01) : 0) |
((MASK & 0x02) ? (val & 0x02) : 0) |
...etc...
((MASK & 0x80) ? (val & 0x80) : 0) |
)
但是步骤,我有点陷入僵局。对于带有局部变量的C++模板函数,我可以做些什么来获得C中C++模板的相同功能?
请注意,使用内联C函数不是一个答案,因为编译器在编译时不会知道MASK的值,因此所有比较都不会优化,因此将成为最终编译输出的一部分。
还要注意,更改#define以包含结果值也不是一个答案,因为这会更改"函数"的签名。
最后,我充分意识到这个谜题可能没有答案。
让您的宏尝试执行模板所做的操作;创建一个内联函数--
#define Foo(MASK, val) inline uint8_t Foo_##MASK(uint8_t val)
{
uint8_t step = 0;
uint8_t result = 0;
if(MASK & 0x01) {result |= (val & 0x01) >> step; ++step;}
if(MASK & 0x02) {result |= (val & 0x02) >> step; ++step;}
//...etc...
if(MASK & 0x80) {result |= (val & 0x80) >> step; ++step;}
return result;
}
怎么样(GCCism):
#define Foo(MASK, val) ({
uint8_t step = 0;
uint8_t result = 0;
if(MASK & 0x01) {result |= (val & 0x01) >> step; ++step;}
if(MASK & 0x02) {result |= (val & 0x02) >> step; ++step;}
//...etc...
if(MASK & 0x80) {result |= (val & 0x80) >> step; ++step;}
result;})
你只是在做一个错误的假设
请注意,使用内联C函数并不是一个答案,因为编译器在编译时将不知道MASK的值,因此所有比较不会得到优化,因此将成为最终编译输出。
我刚刚测试过,gcc能够毫无问题地内联所有内容:
static inline
unsigned Foo(unsigned MASK, unsigned char val)
{
unsigned char step = 0;
unsigned char result = 0;
if(MASK & 0x01) {result |= (val & 0x01) >> step; ++step;}
if(MASK & 0x02) {result |= (val & 0x02) >> step; ++step;}
//...etc...
if(MASK & 0x80) {result |= (val & 0x80) >> step; ++step;}
return result;
}
int main(int argc, char *argv[]) {
return Foo(0x02, argc);
}
导致以下main
:的汇编程序
main:
.LFB1:
.cfi_startproc
andl $2, %edi
movzbl %dil, %eax
ret
.cfi_endproc
.LFE1:
.size main, .-main
clang在功能上也是如此。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗