C++ 这篇关于确定参数传递给函数的方法的技巧给我带来了一些困惑

C++ 这篇关于确定参数传递给函数的方法的技巧给我带来了一些困惑,c++,function,parameter-passing,C++,Function,Parameter Passing,这里有一个技巧让我有些困惑:“让最好的传递方法通过值传递内置类型,通过引用常量传递其他类型”现在我有一些问题如下: 1-首先,我认为建议将引用传递到常量背后的原因是,如果引用的对象不是易失性的,编译器可以将其转换为按值传递,如果效率更高,但如果有一种特殊的语法,我们可以告诉编译器确定最佳值,那么对我来说更有意义自己传递方法我不在乎它会是什么样子,但编译器将passby引用改为constant改为passby value对我来说似乎有点混乱,按照现在的方式,如果我们希望编译器遵循对常量的按引用传递

这里有一个技巧让我有些困惑:“让最好的传递方法通过值传递内置类型,通过引用常量传递其他类型”现在我有一些问题如下:

1-首先,我认为建议将引用传递到常量背后的原因是,如果引用的对象不是易失性的,编译器可以将其转换为按值传递,如果效率更高,但如果有一种特殊的语法,我们可以告诉编译器确定最佳值,那么对我来说更有意义自己传递方法我不在乎它会是什么样子,但编译器将passby引用改为constant改为passby value对我来说似乎有点混乱,按照现在的方式,如果我们希望编译器遵循对常量的按引用传递并使用指针,我们必须强制它这样做,因为它可能决定更有效的方式是按值传递;你能不能让我轻松一点为什么会这样

2-是否“按值传递内置类型”包括内置类型,其大小大于我的平台上类似指针的长双精度的大小,该平台有8个字节,而指针大小为4个字节,并且“通过引用常量传递非内置类型”包括以下内容,这些内容可能会像内置类型一样在内存中传输:

struct Test1{
 public:
  char characters[2];
};
struct Test2{
 public:
  char characters[4];
};
我们可以使用的特殊语法 在这里告诉编译器ok 你自己最好的传球方法是什么

Boost提供了这一点,如
Boost::call_traits::param_type

为什么会这样

可能是因为经验法则在大多数情况下都有效。如果有疑问,您可以通过const引用进行传递,它的效率不太可能非常低

事实上,一般技巧比你所说的要多得多——“小”类型不是内置的,通常也是按值传递的最佳方式。例如,标准库始终按值传递迭代器

是否“按值传递内置类型” 包括更大的内置类型 在大小上大于指针的大小

对。你可以合理地期待一个C++实现通过一个“代码”>“双< /代码>或长双值,几乎所有的实际目的都是可接受的效率。如果你已经到了优化阶段,这是最容易实现的结果,那么你就超越了一般的技巧。你可以在你的实际计划中衡量这两个方面

如果引用的对象不是 编译器可以转换它 如果它更大,则按值传递 有效的

也许吧。如果调用成功内联,那么编译器几乎可以做任何事情。如果调用目标对编译器不可用,那么它就不能这样做,因为实际上,value与const reference参数之间的更改需要同时更改调用者和被调用者代码。此外,别名意味着除非编译器有很多关于正在发生的事情的信息,否则即使使用非易失性对象,也不一定假设它不会改变:

int foo(const int &a, int &b) {
    b = 2;
    return a;
}
除非是内联的,否则此代码不能更改为按值传递
a
,因为有人可能会这样调用它:

int a = 1;
std::cout << foo(a,a);
inta=1;
标准::cout
我们可以使用的特殊语法
在这里告诉编译器ok
你自己最好的传球方法是什么

Boost提供了这一点,如
Boost::call_traits::param_type

为什么会这样

可能是因为经验法则在大多数情况下都有效。如果有疑问,您可以通过const引用进行传递,它的效率不太可能非常低

事实上,一般技巧比你所说的要多得多——“小”类型不是内置的,通常也是按值传递的最佳方式。例如,标准库始终按值传递迭代器

是否“按值传递内置类型” 包括更大的内置类型 在大小上大于指针的大小

对。你可以合理地期待一个C++实现通过一个“代码”>“双< /代码>或长双值,几乎所有的实际目的都是可接受的效率。如果你已经到了优化阶段,这是最容易实现的结果,那么你就超越了一般的技巧。你可以在你的实际计划中衡量这两个方面

如果引用的对象不是 编译器可以转换它 如果它更大,则按值传递 有效的

也许吧。如果调用成功内联,那么编译器几乎可以做任何事情。如果调用目标对编译器不可用,那么它就不能这样做,因为实际上,value与const reference参数之间的更改需要同时更改调用者和被调用者代码。此外,别名意味着除非编译器有很多关于正在发生的事情的信息,否则即使使用非易失性对象,也不一定假设它不会改变:

int foo(const int &a, int &b) {
    b = 2;
    return a;
}
除非是内联的,否则此代码不能更改为按值传递
a
,因为有人可能会这样调用它:

int a = 1;
std::cout << foo(a,a);
inta=1;
标准::cout
  • 编译器可能会在感觉最好的时候优化参数传递。在这个具体的例子中我不知道,但一般来说,编译器在每一步都会进行各种前端和后端优化。因此,我认为您不需要向编译器传递任何“特殊语法”

  • 是的,通过值传递意味着即使基元/内置数据类型大于内存指针或寄存器。在32位体系结构上,双精度(64位/8字节)和长精度双精度(80位/10字节)占用多个寄存器

  • 编译器可能会在感觉最好的时候优化参数传递。在这个具体的例子中我不知道,但一般来说,编译器在每一步都会进行各种前端和后端优化。因此,我认为您不需要向编译器传递任何“特殊语法”