C++ 函数重载-T和对T的引用
可能重复:C++ 函数重载-T和对T的引用,c++,C++,可能重复: 假设函数f有不同的参数: void f(int) { } void f(int&) { } int main() { int a = 42; f(a); } 如何调用void f(int&)?您可以说f(static_cast(a)>)来强制使用int重载。非常量重载不能通过参数消除歧义,但可以强制转换函数本身: static_cast<void(&)(int&)>(f)(a); static_cast(f)(a); (当然,您可以像
假设函数f有不同的参数:
void f(int)
{
}
void f(int&)
{
}
int main()
{
int a = 42;
f(a);
}
如何调用void f(int&)?您可以说f(static_cast(a)>)
来强制使用int
重载。非常量重载不能通过参数消除歧义,但可以强制转换函数本身:
static_cast<void(&)(int&)>(f)(a);
static_cast(f)(a);
(当然,您可以像这样手动选择特定的重载,因此这不再是真正的“重载解析”)您可以说f(static_cast(a)>)
来强制使用int
重载。非常量重载不能通过参数消除歧义,但可以强制转换函数本身:
static_cast<void(&)(int&)>(f)(a);
static_cast(f)(a);
(当然,您可以像这样手动选择特定的重载,因此这不再是真正的“重载解决方案”)您可以执行以下操作:
int main()
{
int a = 42;
void (*fp)(int&) = &f; // (A)
fp(a);
}
这里,我们使用一个函数指针,指向一个重载函数f
。编译器将选择适当的函数使第(A)行工作。注意,我没有使用石膏;这样,如果我更改了函数签名,使得上面的操作不起作用,编译器将发出一个错误,而不是允许代码调用未定义的行为
尽管在这种情况下,最好只是给这两个函数取不同的名称。像这样:
void take_f(int) {}
void modify_f(int&) {}
int main()
{
int a = 42;
modify_f(a);
}
这允许代码具有更清晰的意图,并且不会出现重载问题。当然,你可以想出比take\u f()
和modify\u f()
更好的名字
无论如何,这样做更有意义,因为一个函数使用
int
和另一个函数使用int&
可能是一个很好的迹象,表明它们正在做显著不同的事情(因此需要不同的函数名)。您可以这样做:
int main()
{
int a = 42;
void (*fp)(int&) = &f; // (A)
fp(a);
}
这里,我们使用一个函数指针,指向一个重载函数f
。编译器将选择适当的函数使第(A)行工作。注意,我没有使用石膏;这样,如果我更改了函数签名,使得上面的操作不起作用,编译器将发出一个错误,而不是允许代码调用未定义的行为
尽管在这种情况下,最好只是给这两个函数取不同的名称。像这样:
void take_f(int) {}
void modify_f(int&) {}
int main()
{
int a = 42;
modify_f(a);
}
这允许代码具有更清晰的意图,并且不会出现重载问题。当然,你可以想出比take\u f()
和modify\u f()
更好的名字
无论如何,这样做更有意义,因为一个函数使用
int
和另一个函数使用int&
可能是一个很好的迹象,表明它们正在做显著不同的事情(因此需要不同的函数名)。所以,更一般的问题-引用不是类型T的一部分吗?我的意思是,对于星号,它可以正常工作。@innochenti:引用是类型的一部分,但这两个重载是不明确的,因为类型为int
的左值同样可以绑定到int
和int&
。所以,更一般的问题是-引用不是类型T的一部分?我的意思是,对于asterisk,它可以正常工作。@innochenti:引用是类型的一部分,但这两个重载是不明确的,因为int
类型的左值同样可以绑定到int
和int&
。