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