C++ 中的函数重载按值或按引用传递参数

Function overloading in C++ passing arguments by value or by reference

如果我们在 C++ 中有这个示例函数代码

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

在调用参数中做任何修改是否可以区分要调用的函数?

如果通过以下某些方式调用函数 foo:

foo( 10);

i = 10;
foo( static_cast<const int>(i));

foo( static_cast<const int&>(i)); 

它被称为第一个 foo 重载函数,因为它不能通过引用将 const 参数传递给非常量参数。 但是,您将如何调用第二个 foo 重载函数? 如果我调用下一个方式:

int i = 10;
foo( i);

它发生了一个不明确的错误,因为这两个函数都对这个参数有效。

在此link 中解释了一种解决方法:使用对象而不是内置类型,并将复制构造函数私有化,因此它不能复制对象value 并且必须调用第二个 foo 重载函数并通过引用传递对象。但是,内置类型有什么办法吗?我必须更改函数名称以避免重载?

您可以对 select 重载函数进行(函数的)转换:

static_cast<void (&)(int&)>(foo)(i);

Demo

在大多数情况下,函数重载涉及不同的参数类型和不同的输入参数长度。

您的尝试通常是一种不好的做法,生成的编译代码依赖于编译器,代码优化甚至可能使事情变得更糟。

您可以考虑简单地向第二个方法添加第二个参数,如下所示:

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

其中 ... 可以是布尔类型,例如:bool anotherFunction

所以调用 foo(param1, param2) 只会调用第二个代码,大家都很好。

尽管 @Jarod42 的回答很好,但作为替代解决方案,您可以依赖模板化入口点和内部函数的重载(当然,如果您不想处理显式强制转换)。
它遵循一个最小的工作示例:

#include<type_traits>
#include<iostream>
#include<utility>

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

template<typename T>
void foo(T &&t) {
    static_assert(std::is_same<std::decay_t<T>, int>::value, "!");
    foo_i(0, std::forward<T>(t));
}

int main() {
    foo( 10);
    int i = 10;
    foo( static_cast<const int>(i));
    foo( static_cast<const int &>(i)); 
    foo(i);
}

static_assert 用于检查参数是否涉及 int(即 intint &const int &、int &&` 等等)。

从上面的代码可以看出,foo(i)会打印:

foo(int &)

符合预期。

非常奇怪的设计,但如果您需要...我会提供一个与您的设计一样奇怪的解决方案 在函数签名中使用 Xreference。然后在函数中,您可以使用 std::is_lvalue_referencestd::is_rvalue_reference.
检查您需要做什么 像这样

template<class T>
void foo(T&& x)
{
  static_assert(std::is_same<std::decay_t<T>, int>::value, "!"); 
  if (std::is_rvalue_reference<T&&>::value)
    std::cout << "do here what you want in foo(int x)";
  else
    std::cout << "do here what you want in foo(int & x)";
}

int main()
{
  int x = 5;
  foo(x); //"do here what you want in foo(int x)" - will be printed
  foo(std::move(x)); //"do here what you want in foo(int & x)" - will be printed
}

另一个:

#include <iostream>
#include <functional>

void foo(int x)
{
    std::cout << "foo(int)\n";
}

template<typename T>
void foo(T&& x)
{
    std::cout << "foo(int&)\n";
}

int main()
{
    int i = 10;
    foo(i);           // foo(int)
    foo(std::ref(i)); // foo(int&)
}