Page 1 of 1

Gibt es eine Möglichkeit mit type_traits zu überprüfen, ob ein Typ mit range-for kompatibel ist?

Posted: 07 Jan 2025, 14:01
by Guest
Stellen Sie sich eine Klasse vor, die einen auf Vorlagen basierenden „iterierbaren“ Typ wie diesen verwendet:

Code: Select all

template 
struct foo {
void bar(Iterable& collection) {
for (const auto& item : collection) {
// ...
}
}
};
Gibt es eine -Möglichkeit, den Iterable-Typ auf Typen zu beschränken, die mit der Range-for-Schleife kompatibel sind?

Code: Select all

template 
Nichts wie std::is_range_for_iterable fällt mir auf der Liste der Typmerkmale von cppreference auf. Deshalb habe ich genauer untersucht, was es eigentlich bedeutet, „kompatibel mit Range-for“ zu sein:

Exposition-only-Ausdrücke /* begin-expr */ und /* end-expr */ sind wie folgt definiert:
  • Wenn der Typ von /* range */ ist ein Verweis auf einen Array-Typ R:

    Wenn R von ist gebunden N, /* begin-expr */ ist /* range */ und /* end-expr */ ist /* range */ + N.
  • Wenn R ein Array mit unbekannter Grenze oder ein Array mit unvollständigem Typ ist, ist das Programm falsch formatiert.
[*]Wenn der Typ von /* range */ eine Referenz ist zu einem Klassentyp C und sucht im Gültigkeitsbereich von C nach den Namen begin und end. Findet jeweils mindestens eine Deklaration, dann ist /* begin-expr */ /* range */.begin() und /* end-expr */ ist /* range */.end().
[*]Sonst /* begin-expr */ ist begin(/* range */) und /* end-expr */ ist end(/* range */), wobei begin und end über eine argumentabhängige Suche (nicht ADL-Suche) gefunden werden wird nicht ausgeführt).


Aus dieser Beschreibung kann ich möglicherweise etwas zusammenbrauen, indem ich is_array verwende für den ersten Fall und is_function oder is_invocable zu Suchen Sie nach passenden begin()- und end()-Funktionen für die anderen beiden Fälle. Aber ich befürchte, dass dies ein ziemliches Durcheinander wäre und sehr wahrscheinlich zu Eckfällen führen würde (Szenarien, die tatsächlich kompatibel sind, und umgekehrt, lehne ich ab).
Gibt es eine? einfacher oder bereits etablierter Weg?
C++20-Konzepte bieten hierfür eine viel schönere Lösung, aber ich suche nach einer C++17-Lösung, bei der type_traits das beste verfügbare Tool ist .