Zur Realisierung:
Ich würde da einfach schauen lassen, in welchem Kontext die Funktion aufgerufen wird und dann entscheiden lassen, welche Funktion genommen wird.
Das heisst, du musst massiv viele Aufrufe, bei denen der erwartete Typ nicht 100% dem Rückgabetyp entspricht, verbieten.
|
C-/C++-Quelltext
|
1
|
long l = foo(); // Fehler
|
Das heisst auch, Benutzung in Templates ist unmöglich, weil mehrdeutig.
|
C-/C++-Quelltext
|
1
2
3
4
|
template <typename T>
void bar(T t);
bar(foo()); // Fehler
|
Ausserdem heisst das, Ausdrücke der folgenden Art müssten verboten werden (wenn du meinst, bool hätte in arithmetischen Ausdrücken nichts zu suchen, nimm short vs. int).
|
C-/C++-Quelltext
|
1
|
2.3 * foo() // Fehler
|
Dein Ansatz würde also das halbe Typsystem von C++ über den Haufen werfen.
Es ist nicht mehr möglich, den Typ eines Ausdrucks zu bestimmen. Implizite Konvertierungen zwischen arithmetischen Typen gehören zur Sprache, Überladung des Rückgabetypen würde diese sehr stark einschränken.
Das, was du erreichen willst, lässt sich bereits jetzt über benutzerdefinierte Konvertierungsoperatoren implementieren:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
struct MyClass
{
operator int() const
{
std::cout << "INT" << std::endl;
return 33;
}
operator bool() const
{
std::cout << "BOOL" << std::endl;
return false;
}
};
int main()
{
MyClass c;
int a = c;
bool b = c;
if (MyClass())
{
std::cout << "OK" << std::endl;
}
}
|
Der Code ist eindeutig, das Verhalten wie erwartet.