ambiguous call to overloaded function - int and in

2019-01-15 20:08发布

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();
}

Is there a way to avoid ambiguous call error here ? something like g( static_cast<int&>(a) );

3条回答
够拽才男人
2楼-- · 2019-01-15 20:53

This answer relates to the question as it was when I answered.

The OP keeps adding to the question, and I'm not going to chase that…


Yes there is, and yes, you're right that it involves casting to resolve the ambiguity:

#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 );
}

Note: to run this in Visual Studio and see the result window, either use [Ctrl F5], or place a breakpoint on the last right brace of main and run it in the debugger. But better, just run it from the command line. No need to add a “stop” at the end! :-)


AMENDMENT: Dietmar showed in his answer how to use a cast to const to call the by-value argument overload. I didn't even think of that, but if you want to do that (it's limited to cutting off the by-reference version from consideration), do use a const_cast instead of a static_cast.

Or better, just make an rvalue expression out of the argument, e.g. by adding a handy little + sign in front,

    g( +a );

:-)

查看更多
在下西门庆
3楼-- · 2019-01-15 20:54

If you can cast, there is, of course a way to disambiguate the call:

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

If you insist to call the reference version, the resolution is a bit more tricky:

static_cast<void(*)(int&)>(g)(a);
查看更多
一夜七次
4楼-- · 2019-01-15 21:01

For the purpose of overload resolution, binding to a reference of the correct type is an exact match, exactly like binding to a non-reference of the correct type, so the two overloads have identical priority with respect to an lvalue int argument.

You could make the second overload take a int const &, in which case it can be used in the exact same way but will be a distinct overload.

Alternatively, you could avoid overload resolution altogether by casting the function type:

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

You would have to do this for every invocation of the function where there is an ambiguity, though (i.e. when passing an lvalue int).

This video is mandatory viewing for you.

查看更多
登录 后发表回答