I realize standard C++ only picks functions by argument type, not return type. I.e I can do something like:
void func(int);
void func(double);
but not
double func();
int func();
Where in the former, it's clear, in the latter, it's ambigious. Are there any extensions that lets me tell C++ to pick which function to use also by return type?
Thanks!
You cannot have two functions in the same scope that have the same name and signature (ie. argument types). Yet you can create a function that will behave differently depending on what variable you assign the result to, as in:
int x=f();
double x=f(); // different behaviour from above
by making f()
return a proxy with an overloaded cast operator.
struct Proxy
{
operator double() const { return 1.1; }
operator int() const { return 2; }
};
Proxy f()
{
return Proxy();
}
See http://ideone.com/ehUM1
Not that this particular use case (returning a different number) is useful, but there are uses for this idiom.
If you had those two functions, which one should the compiler pick if you simply called:
func();
The closest you can get to what you are asking for would be to use a specialized function template (note that you want to be very careful when specializing function templates):
template <typename ReturnT>
ReturnT func();
template <>
double func<>() { return 42; }
template <>
int func<>() { return 0; }
Then you can call it as follows:
func<int>();
func<double>();
Why not just name them differently? If they're returning different things, it sounds to me as though they're probably doing different things. Why obfuscate your code?
There's one context in C++ where the result of overload resolution depends on the "return type", on the left-hand side of the expression. It is initialization/assignment of the function pointer value with the address of a function. It works with an explicit object of the left-hand size as well as with a temporary object created by an explicit type cast.
In your case it can be used to select one specific function from two overloaded ones. For example:
int (*pfunc)() = func; // selects `int func()`
int i = pfunc(); // calls `int func()`
You can use this technique to force overload resolution in one line, although it doesn't look too elegant
int i = ((int (*)()) func)(); // selects and calls `int func()`
Again, in this case you perform the overload resolution manually. C++ has no feature that would result in implicit overload resolution based on the return type (aside from what I illustrated above).
Because compiler don't know what function you calls!
No; it's actually pretty hard to implement too. I vaguely remember hearing that it was a P-NP problem.
None that I know of. You'd best name the functions differently or perhaps use a different argument to let the compiler (not you) distinguish them.
Alternatively, do:
struct myReturnType {
int myInt;
double myDouble;
};
myReturnType func() {
...
}
It's a bit dangerous, but you can create a union of the different types that you want to return, and combine both of these into one function that returns a union. For example:
typedef union {
double d;
int i;
} my_union;
my_union func();
However, this would require the function and the caller to somehow know what data type to expect as a result, and can lead to all sorts of errors. You can do this, but I definitely wouldn't recommend it.
function overloading requires different signatures of each form excluding the return type. two or more forms are correct if only and if they at list differ in number of parameters or at least one type or the the order of parameters eg:
void print(); // 1
void print(int, char); // 2 ok number of parameters
void print(char, int); // 3 ok the order of parameters type
int print(int, char); // 4 no the same signature as 2 except the return type
精彩评论