Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bedingte Ueberladung

13 views
Skip to first unread message

Stefan Reuther

unread,
May 15, 2017, 1:50:04 PM5/15/17
to
Cheers,

aus verschiedenen Gründen möchte ich eine Funktion einmal für 'uint32_t'
überladen und einmal für 'size_t'. Dummerweise ist das auf gängigen
Systemen der gleiche zugrundeliegende Datentyp, und zweimal auf den
gleichen Typ überladen geht nicht.

Gibt es eine einfache Möglichkeit, die zweite Überladung nur anzulegen,
wenn sie notwendig ist? (Bonuspunkte für C++03-Kompatibilität.)

Die auf SFINAE basierenden Lösungen funktionieren nur, wenn eine
Abhängigkeit von einem Templateparameter drin ist.

Als Workaround hab ich jetzt erstmal ein
void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
uint64_t, size_t>::type);
sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
uint64_t"; das geht in dem Fall zufällig und stört nicht.


Stefan

Stefan Ram

unread,
May 16, 2017, 6:50:03 AM5/16/17
to
Stefan Reuther <stefa...@arcor.de> writes:
>Als Workaround hab ich jetzt erstmal ein
> void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
> uint64_t, size_t>::type);
>sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
>uint64_t"; das geht in dem Fall zufällig und stört nicht.

Etwas Besseres fällt mir derzeit auch nicht ein.

Du könntest vielleicht noch »uint64_t« durch einen
Einmaltyp ersetzen, der von außen nicht erreichbar ist,
falls es später einmal Fälle geben sollte, in denen die
unerwünschte Überladung stören sollte.

Falls die Funktion auch in einer Klassenschablone sein
darf, dann würde dadurch noch verhindert werden, daß
Code für sie generiert wird.

Dadurch wäre die Funktion effektiv kaum existent (nicht
erreichbar, und es wird kein Code generiert).

Markus Schaaf

unread,
May 16, 2017, 8:00:03 AM5/16/17
to
Am 15.05.2017 um 19:07 schrieb Stefan Reuther:

> aus verschiedenen Gründen möchte ich eine Funktion einmal für 'uint32_t'
> überladen und einmal für 'size_t'. Dummerweise ist das auf gängigen
> Systemen der gleiche zugrundeliegende Datentyp, und zweimal auf den
> gleichen Typ überladen geht nicht.

Template-Foo ist ja nett, aber in diesem Fall ist der gute alte
Präprozessor wohl die richtige Wahl:

#include <stdint.h>

void foo( uint32_t );

#if SIZE_MAX != UINT32_MAX

void foo( size_t );

#endif

MfG

Stefan Reuther

unread,
May 16, 2017, 1:30:04 PM5/16/17
to
Hrmpf. Das ist ja viel zu einfach, um da drauf zu kommen. :-) Löst
diesen Fall aber recht elegand.

Danke,

Stefan

Stefan Reuther

unread,
May 16, 2017, 1:30:04 PM5/16/17
to
Am 16.05.2017 um 12:47 schrieb Stefan Ram:
> Stefan Reuther <stefa...@arcor.de> writes:
>> Als Workaround hab ich jetzt erstmal ein
>> void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
>> uint64_t, size_t>::type);
>> sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
>> uint64_t"; das geht in dem Fall zufällig und stört nicht.
>
> Etwas Besseres fällt mir derzeit auch nicht ein.
>
> Du könntest vielleicht noch »uint64_t« durch einen
> Einmaltyp ersetzen, der von außen nicht erreichbar ist,
> falls es später einmal Fälle geben sollte, in denen die
> unerwünschte Überladung stören sollte.

Der Einmaltyp scheitert daran, dass der Funktionsrumpf ja weiterhin
gültig sein muss. Im Funktionsrumpf wird mit dem Parameter gerechnet,
also müsste ich die Rechenoperatoren für den Einmaltyp auch noch
wenigstens deklarieren. Davon geht die Welt nicht unter, macht's aber
noch unübersichtlicher.


Stefan

Florian Weimer

unread,
May 17, 2017, 5:50:03 AM5/17/17
to
* Stefan Reuther:

> Als Workaround hab ich jetzt erstmal ein
> void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
> uint64_t, size_t>::type);
> sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
> uint64_t"; das geht in dem Fall zufällig und stört nicht.

Funktioniert das auf s390? Siehe zum Beispiel:

<https://bugzilla.redhat.com/show_bug.cgi?id=1163188>

Stefan Reuther

unread,
May 17, 2017, 1:30:03 PM5/17/17
to
Am 16.05.2017 um 20:25 schrieb Florian Weimer:
> * Stefan Reuther:
>> Als Workaround hab ich jetzt erstmal ein
>> void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
>> uint64_t, size_t>::type);
>> sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
>> uint64_t"; das geht in dem Fall zufällig und stört nicht.
>
> Funktioniert das auf s390? Siehe zum Beispiel:

Keine Ahnung, hast du mal ein System zum Testen? :-) Auf x64 vs. x86
funktioniert's jedenfalls.

> <https://bugzilla.redhat.com/show_bug.cgi?id=1163188>

Es gibt noch einen zweiten Overload mit uint32_t.

Die Idee ist: wenn size_t == uint32_t, dann nehmen sowohl die Aufrufe
'foo(size_t(1))' als auch 'foo(uint32_t(1))' diesen ersten Overload. Der
zweite muss dann nur einen anderen Datentyp haben, der in der
Overload-Auflösung schlechter dasteht. Das wäre hier 'uint64_t', könnte
aber sicher auch jeder andere Integer-Typ sein.


Stefan

Florian Weimer

unread,
May 18, 2017, 4:40:03 AM5/18/17
to
* Stefan Reuther:

> Am 16.05.2017 um 20:25 schrieb Florian Weimer:
>> * Stefan Reuther:
>>> Als Workaround hab ich jetzt erstmal ein
>>> void foo(if_then_else<is_same_type<uint32_t,size_t>::value,
>>> uint64_t, size_t>::type);
>>> sprich, "wenn uint32_t gleich size_t, überlade das auch noch für
>>> uint64_t"; das geht in dem Fall zufällig und stört nicht.
>>
>> Funktioniert das auf s390? Siehe zum Beispiel:
>
> Keine Ahnung, hast du mal ein System zum Testen? :-)

Ja.

> Auf x64 vs. x86 funktioniert's jedenfalls.

s390 ist in dieser Hinsicht etwas eigen.

Ich kann's gerne mal ausprobieren, wenn Du ein vollständiges
Minimalbeispiel hast.
0 new messages