gpt4 book ai didi

c++ - 函数指针的 Type(f)(Type) 和 Type(*f)(Type) 之间的区别?

转载 作者:太空狗 更新时间:2023-10-29 19:49:07 26 4
gpt4 key购买 nike

这两个函数原型(prototype)有什么区别?

void apply1(double(f)(double));
void apply2(double(*f)(double));

如果目标是将提供的函数应用于数组,是否有比另一个更快的版本?

编辑:实现示例:

#include <iostream>
#include <vector>
#include <cmath>

// First version
template<typename Type> void apply1(std::vector<Type>& v, Type(f)(Type))
{
for (unsigned int i = 0; i < v.size(); ++i) {
v[i] = f(v[i]);
}
}

// Second version
template<typename Type> void apply2(std::vector<Type>& v, Type(*f)(Type))
{
for (unsigned int i = 0; i < v.size(); ++i) {
v[i] = f(v[i]);
}
}

// Main
int main()
{
std::vector<double> v = {1., 2., 3., 4., 5.};
apply1(v, std::sin);
apply2(v, std::sin);
return 0;
}

最佳答案

首先,模板包装器实例化的速度几乎完全取决于优化器。

也就是说,我已将您的样本缩减为我能想到的最基本的代码,专门用于检查函数参数的调用。您可以继续阅读,但您会发现它们调用的方式完全相同。一项声明与另一项声明没有任何好处。此外,我包括了你遗漏的那个,(reference-decl)

#include <cstdio>

int hello(int x)
{
return x;
}

template<typename Type>
void apply1(Type x, Type (f)(Type))
{
f(x);
}

template<typename Type>
void apply2(Type x, Type (*f)(Type))
{
f(x);
}

template<typename Type>
void apply3(Type x, Type (&f)(Type))
{
f(x);
}

int main(int argc, char *argv[])
{
apply1(1,hello);
apply2(2,hello);
apply3(3,hello);
return 0;
}

扣除产生的实际asm是:

申请1

__Z6apply1IiEvT_PFS0_S0_E:
Leh_func_begin2:
pushq %rbp
Ltmp2:
movq %rsp, %rbp
Ltmp3:
subq $16, %rsp
Ltmp4:
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movq -16(%rbp), %rax
movl -4(%rbp), %ecx
movl %ecx, %edi
callq *%rax
addq $16, %rsp
popq %rbp
ret
Leh_func_end2:

申请2

__Z6apply2IiEvT_PFS0_S0_E:
Leh_func_begin3:
pushq %rbp
Ltmp5:
movq %rsp, %rbp
Ltmp6:
subq $16, %rsp
Ltmp7:
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movq -16(%rbp), %rax
movl -4(%rbp), %ecx
movl %ecx, %edi
callq *%rax
addq $16, %rsp
popq %rbp
ret
Leh_func_end3:

申请3

__Z6apply3IiEvT_RFS0_S0_E:
Leh_func_begin4:
pushq %rbp
Ltmp8:
movq %rsp, %rbp
Ltmp9:
subq $16, %rsp
Ltmp10:
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movq -16(%rbp), %rax
movl -4(%rbp), %ecx
movl %ecx, %edi
callq *%rax
addq $16, %rsp
popq %rbp
ret
Leh_func_end4:

它们相同(正如我所怀疑的那样)。我能看到什么都没有区别。

注意:值得一提的是编译器通过名称修改检查查看这些声明的方式:

apply1: __Z6apply1IiEvT_PFS0_S0_E
apply2: __Z6apply2IiEvT_PFS0_S0_E
apply3: __Z6apply3IiEvT_RFS0_S0_E

关于c++ - 函数指针的 Type(f)(Type) 和 Type(*f)(Type) 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13226942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com