是否通过使用数字文字调用函数来创建临时对象?

Does a temporary object gets created by calling a function with a numeric literal?

假设我有一些简单的东西,比如:

void f(int a){...}
int main()
{
   f(3);
   return 0;
}

当我们调用 f(3) 时,初始化是如何在稍低的抽象层次上发生的?创建的临时对象的值为 3 还是仅通过复制初始化进行初始化?

问这个问题的主要原因是我在这段代码中遇到了这个问题:

void f(int a){...}
void f(int&& a){...}
int main()
{
   f(3);
   return 0;
}

...我收到一条错误消息,说它不明确。因为我很确定调用函数 f(int&& a) 我们会创建一个临时对象,它会通过引用 a 延长生命周期,我还要说调用 f(int a) 也会调用 a 的创建暂时的。否则,编译器不应该选择调用 f(int a) 更有效吗?

还有没有一本书可以优雅地涵盖这个主题?

在语义上(忘记内联、优化和其他东西)第一个片段不需要临时的。

void f(int a){...}

当您在 f(3) 中调用此函数时,将使用 int 的(伪)复制构造函数创建一个整数对象作为函数参数。这成为函数的局部参数,并且它的生命周期在函数 returns.

时结束

与此同时,第二个片段

void f(int&& a){...}

需要调用代码来创建临时 int 变量(因为您不能将任何类型的引用绑定到数字文字)。之后,右值引用被绑定到临时创建的。

关于您 'efficiency' 的问题,编译器不会 select 基于效率的函数重载。他们根据一定的转化排名来执行此操作,在您的情况下,副本和参考绑定具有相同的排名。您可以在此处阅读有关重载决议的更多信息:https://en.cppreference.com/w/cpp/language/overload_resolution