C++ 基于值与常量引用的函数重载

C++ 基于值与常量引用的函数重载,c++,pass-by-reference,pass-by-value,overloading,C++,Pass By Reference,Pass By Value,Overloading,声明类似于以下内容吗 void foo(int x) { std::cout << "foo(int)" << std::endl; } void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; } < >不在C++中。功能语言如Erlang和Haskell可以通过允许基于参数值指定函数重载来更接近,但是大多数命令语言

声明类似于以下内容吗

void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }

< >不在C++中。功能语言如Erlang和Haskell可以通过允许基于参数值指定函数重载来更接近,但是大多数命令语言包括C++都需要基于方法签名的重载;即每个参数的数量和类型以及返回值的类型

签名中的
const
关键字定义的不是参数的类型,而是其在函数中的可变性;如果函数修改了“
const
”参数,或通过引用传递给任何不使用
const
的函数,则该参数将生成编译器错误

打电话的人如何区分他们


在这种情况下无法区分。这两个重载函数都具有与参数相同的原始数据类型类型。而通过引用获取并不适用于不同的类型。

其目的似乎是区分带有临时变量的调用(即
9
)和“常规”参数传递。第一种情况可能允许函数实现采用优化,因为很明显,参数将在之后处理(这对于整数文本毫无意义,但对于用户定义的对象可能有意义)

然而,当前C++语言标准并没有提供一种特别适合参数“L/R值”的方法,任何L值作为参数传递给函数都可以隐式转换为引用,所以歧义是不可避免的。 C++11为类似的目的引入了一个新工具——使用r值引用,可以如下重载

void foo(int x)        { ... }
void foo(const int &&x) { ... }
。。。而
foo(4)
(作为参数传递的临时r值)将导致编译器在
inti=2时选择第二个重载;foo(i)
会选择第一个

(注意:即使使用新的工具链,也无法区分示例中的案例2和案例3!)

编译器无法区分。 foo的两个定义都可以用于int的所有“变体”

在第一个foo中,创建int的副本。复制int始终是可能的

在第二个foo中,传递对const int的引用。由于任何int都可以转换为const int,因此也可以传递对它的引用

由于这两个变量在所有情况下都有效,编译器无法选择

如果使用以下定义,情况会有所不同:

void foo (int &x);
现在用
foo(9)
调用它将采用第一种方法,因为不能将9作为非常量int引用传递


另一个示例是,如果用复制构造函数为私有的类替换int,则调用方无法复制该值,并且不会使用第一个foo变量。

可以使用模板执行此操作:

模板void foo(tx){…}

然后,您可以通过值或引用调用此模板:

int x = 123;
foo<int>(x);  // by value
foo<int const&>(x);  // by refernce
intx=123;
foo(x);//按价值
foo(x);//参照

您可以使用
static\u cast
显式选择要调用的重载:

#include <iostream>

void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }

int main()
{
  int x = 0;

  auto f1 = static_cast< void(*)(int) >(foo);
  f1(x);

  auto f2 = static_cast< void(*)(const int&) >(foo);  
  f2(x);

}
#包括

void foo(int x){std::cout这不是真的,它们是可区分的,请参见@Inverse的答案,这是一个重复的问题。我使用vs2012进行了测试,但它仍然抱怨调用不明确,您确定强制转换到常量引用有效吗?
const int&
对于右值仍然无法与
int
区分。再次,false,请参见。
#include <iostream>

void foo(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }

int main()
{
  int x = 0;

  auto f1 = static_cast< void(*)(int) >(foo);
  f1(x);

  auto f2 = static_cast< void(*)(const int&) >(foo);  
  f2(x);

}
void foo_copying(int x)        { std::cout << "foo(int)"         << std::endl; }
void foo_non_copying(const int &x) { std::cout << "foo(const int &)" << std::endl; }