3
void g(int& a)
{
    std::cout<<"int&\n";
} 

void g(int a)
{
    std::cout<<"int\n";
}  

int main()
{    
    int a = 2;   
    g(a); //won't compile (at least under MSVC 2012)

    std::cin.ignore();
}

有没有办法在这里避免模棱两可的调用错误?就像是g( static_cast<int&>(a) );

4

3 回答 3

10

如果你可以施法,当然有一种方法可以消除通话歧义:

g(const_cast<int const&>(a));

如果您坚持调用参考版本,则解决方案有点棘手:

static_cast<void(*)(int&)>(g)(a);
于 2012-11-13T20:50:05.713 回答
3

出于重载决议的目的,绑定到正确类型的引用是完全匹配的,就像绑定到正确类型的非引用一样,因此两个重载对于左值int参数具有相同的优先级。

可以使第二个重载采用 a int const &,在这种情况下,它可以以完全相同的方式使用,但将是一个不同的重载。

或者,您可以通过转换函数类型来完全避免重载解析:

static_cast<void(&)(int)>(g)(a);
static_cast<void(&)(int&)>(g)(a);

但是,对于存在歧义的函数的每次调用,您都必须这样做(即在传递左值时int)。

该视频是您必须观看的。

于 2012-11-13T20:45:24.587 回答
3

这个答案与我回答时的问题有关。

OP不断增加问题,我不打算追究......


是的,是的,你是对的,它涉及到解决歧义的转换:

#include <iostream>

void g(int& a)
{
    std::cout<<"int&\n";
} 

void g(int a)
{
    std::cout<<"int\n";
}  

int main()
{    
    int a = 2;   
    static_cast< void(*)(int&) >( g )( a );
}

注意:要在 Visual Studio 中运行它并查看结果窗口,请使用 [Ctrl F5],或者在的最后一个右大括号上放置一个断点main并在调试器中运行它。但更好的是,只需从命令行运行它。无需在末尾添加“停止”!:-)


修正Dietmar 在他的回答中展示了如何使用强制转换const来调用按值参数重载。我什至没有想到这一点,但如果你想这样做(它仅限于从考虑中删除引用版本),请使用 aconst_cast而不是 a static_cast

或者更好的是,只需从参数中创建一个右值表达式+,例如在前面添加一个方便的小符号,

    g( +a );

:-)

于 2012-11-13T20:49:20.360 回答