Function overloading - declare a default function?

I'm trying to overload a function in a way that it would accept a reference - if possible, otherwise it would copy the value. I wrote a simple test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void test(double &value) {
	cout << "Value was referenced\n";
}

void test(double value) {
	cout << "Value was copied\n";
}

int main() {
	double var = 12.34;
	test(var); //Error: more than one instance matches the arg list
	test(var-1);
	return 0;
}


Is there any way to declare a default function to be called if more than one instance matches the argument list?
closed account (EzwRko23)
But do you need a reference or value?
They are semantically different things.
Even if this worked, it is a very bad idea and would confuse users of your function.
When something accepts a reference, it tells the caller "I will modify this variable".

Maybe you needed a const reference? Const references can be created from almost everything.
Last edited on
It's simply a matter of memory usage. Let's say I want to do something to a variable and assign it to a new variable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
double test(double &value) {
	return value/2;
}

double test(double value) {
	return value/2;
}

int main() {
	double var1 = 2.0;
	double var2 = test(var1); // assigns half of var1 directly
	double var3 = test(var1+1.0); // creates new variable and then assigns half of it
	return 0;
}


I want to do this for my own convenience, so that I don't have to juggle between two functions while writing the program.
I'm confused on what you actually want to do but it looks like you may as well use:

1
2
3
double test(const double &value) {
        return value/2;
}


In neither of you're functions are you actually modifying the argument given to the function so there's no point really of passing it by reference. Unless of course, you use the code I have provided that uses a const reference; a reference that cannot be modified and does not create a local variable.

Also, by definition this is not function overloading:

In C++ two different functions can have the same name if their parameter types or number are different. That means that you can give the same name to more than one function if they have either a different number of parameters or different types in their parameters.
Last edited on
This is a common misconception. Here's some facts to digest:

- references do not mean less memory usage.
- references do not mean faster code
- basic data types are cheap to copy
- copying basic data types once at the start of a function is often faster than dereferencing a reference several times throughout the life of a function.
- passing everything by reference all the time does not make for faster/better code.
- if the function is small it will likely be inlined anyway (provided it can be), so there's no point in trying to micro-optimize it because the extra var will be optimized out by the compiler anyway.


Here are some very general rules that are applicable to 99.99% of situations:

Pass by value when the argument will not be modified, and is a basic data type (int, double, bool, etc)

The reason for this is because references are often implemented as pointers, and it is just as expensive to copy a pointer as it is to copy a basic data type since they both consume about the same amount of memory. The only difference is if you're accessing a pointer/reference, the code is slower because you have to dereference it everytime you want to access the var, whereas if you make a copy you can just access it directly.

Pass by const reference when the argument will not be modified, and is a complex data type (string, vector, other types of classes)

The reason for this is twofold:

1) Copying large/complex objects can be expensive.

2) You often don't access data members directly anyway. Member functions all have indirection through the 'this' pointer, so accessing member functions through a pointer does not have any overhead. So it's usually not any slower to access an object by pointer/reference than it is to access them directly.

Pass by non-const reference only when the argument is to be modified (ie: it's an "out" argument).

This is a clarity thing more than anything else. Passing by const reference or by value guarantees that the original value will not be changed. So if you pass by reference it implies that the function will change the passed var.

=====

Al of that said, the above test function should pass by value:

1
2
3
4
double test(double value)  // this is the way to do it
{
  return value / 2;
}
Last edited on
I stand corrected.

Disch wrote:
The reason for this is because references are often implemented as pointers, and it is just as expensive to copy a pointer as it is to copy a basic data type since they both consume about the same amount of memory. The only difference is if you're accessing a pointer/reference, the code is slower because you have to dereference it everytime you want to access the var, whereas if you make a copy you can just access it directly.


Thank you for this info! Both interesting and useful.
@Disch: Thanks, that answers my question perfectly! I'm new to programming so I don't quite understand what's really going on under the hood.
Last edited on
Topic archived. No new replies allowed.