Overload resolution (value vs reference)

Jonathan M Davis jmdavisProg at gmx.com
Sun Oct 21 15:46:42 PDT 2012


On Sun, 2012-10-21 at 19:01 +0200, m0rph wrote:
> How does compiler selects the proper function among overloaded
> functions which differ only in the way the argument is passed (by
> reference or by value)? Is there a way, to control this behavior?
> 
> Result of execution of the test code:
> passed by value: 8
> passed by value: 3
> passed by value: Foo(10)
> 
> 
> Test code:
> 
> import std.stdio;
> 
> struct Foo {
>       int value;
> }
> 
> void f(T)(T foo)
> {
>       writeln("passed by value: ", foo);
> }
> 
> void f(T)(const ref T foo)
> {
>       writeln("passed by reference: ", foo);
> }
> 
> void main()
> {
>       // 8 is a r-vlaue, so it's passed by value
>       f(8);
> 
>       // i is a l-value, it's passed by value and it's ok
>       int i = 3;
>       f(i);
> 
>       // foo is a l-value, it's passed by value again, but if
> structure will be big enough it'll be ineffective
> 
>       auto foo = Foo();
>       foo.value = 10;
>       f(foo);
> }
> 

http://dlang.org/function.html#function-overloading

The big thing to remember here is that constness matters more than
refness when overloads are chosen, so if you want refness to matter when
choosing an overload, then the constness of the overloads must match,
and if there's ever a question between const and non-const, it's the
constness of the argument being passed in which wins (e.g. if you have
ref T and const ref T, then which one gets called depends on whether the
argument is const or not).

As your code stands, if it were

void f(T)(T foo)
{
    f(foo);
}

void f(T)(const ref T foo)
{
    //...
}

you would get an infinite loop when passing an rvalue to f, whereas

void f(T)(const T foo)
{
    f(foo);
}

void f(T)(const ref T foo)
{
    //...
}

would not.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list