typedefs und freie Funktionen



  • Hallo zusammen,

    ich habe eine eigene Tupel-Klasse xsp::tuple, die eine leicht abgewandelte Version von std::tuple ist. Jetzt möchte ich in Templates beide Typen verwenden können.
    Für std::tuple existiert ja eine freie Template-Funktion std::get<i>(tuple);
    Jetzt wäre es ja ziemlich dämlich den std-Namensraum für das xsp::tuple zu missbrauchen. Stattdessen soll get<i> im Namensraum xsp liegen.

    Wie mache ich das am elegantesten? Muss ich wirklich einen wrapper schreiben?

    template<typename T> // T kann xsp::tuple oder std::tuple sein
    void doit(T& t){
            typename std::tuple_element<0, T>::type e = std::get<0>(t);
            // typename xsp::tuple_element<0, T>::type e = xsp::get<0>(t);
    }
    

    Gruß,
    XSpille

    EDIT:
    Achso: Das gleiche Problem existiert natürlich auch bei einem typedef, wenn man von std::tuple nach xsp::tuple wechselt oder umgekehrt...



  • EDIT:

    Argh, mit expliziten Template-Parametern geht das mit ADL ja nicht so einfach - da stolpert er ja schon darüber, dass er nicht checkt, dass das ein Funktionsaufruf sein soll.

    Also muss ein pöser Trick her:

    namespace enable_ADL_for_tuple_get
    {
        template <int i, class T>
        int get(T const&, ...); // bitte nirgends implementieren
    }
    
    template<typename T> // T kann xsp::tuple oder std::tuple sein, oder jeder typ
    void doit(T& t){     // für den über ADL ne passende funktion gefunden wird
        using enable_ADL_for_tuple_get::get;
        auto e = get<0>(t); 
    }
    

    Da nun in "doit" ein "get" Funktions-Template sichtbar ist, wird get<0>(t) als Funktionsaufruf erkannt. Und nachdem get<0>(t) als Funktionsaufruf erkannt wurde, wird dann netterweise auch ADL gemacht. Und dann natürlich Overload Resolution.

    enable_ADL_for_tuple_get::get steht immer als Kandidat zur Verfügung. Wenn (über ADL oder auch sonst wie) andere Funktionen als Kandidaten zur Verfügung stehen, dann sollte das "..." dafür sorgen, dass enable_ADL_for_tuple_get::get immer als "schlechter passend" eingestuft wird.

    Und sollte doch mal enable_ADL_for_tuple_get::get ausgewählt werden, dann ist es nirgends definiert, was zum gewünschten Fehler führt.

    ----

    Falls jmd. eine sauberere Lösung kennt, bitte melden 🙂



  • Danke hustbaer!

    Ich kuck noch mal wie ich es löse...


  • Mod

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?



  • camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Weil man manchmal den Wald vor lauter Bäumen nicht sieht 😃



  • camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Weil in header-Dateien nach meiner Einstellung/Meinung kein using reingehört.


  • Mod

    XSpille schrieb:

    camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Weil in header-Dateien nach meiner Einstellung/Meinung kein using reingehört.

    Auf die Begründung bin ich sehr gespannt.



  • XSpille schrieb:

    camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Weil in header-Dateien nach meiner Einstellung/Meinung kein using reingehört.

    Das ist nur ein Problem, wenn du das using frei im Header steht. Lokal in einer Funktion ist es ungefährlich.



  • camper schrieb:

    XSpille schrieb:

    camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Weil in header-Dateien nach meiner Einstellung/Meinung kein using reingehört.

    Auf die Begründung bin ich sehr gespannt.

    Sorry...
    Da ich using nie verwende, war es für mich automatisch frei im Header...



  • camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Ich danke dir!!!

    Es klappt wirklich gut für std::get und xsp::get...

    Allerdings weiß ich noch nicht, wie ich es mit dem
    std::tuple_element bzw. xsp::tuple_element
    hinkriege, da es ja eine class/struct ist.

    error: 'tuple_element' is already declared in this scope



  • Nimm decltype(get<0>(t)) oder auto .
    (Oder wäre hier decltype((get<0>(t))) angesagt 😕)


  • Mod

    XSpille schrieb:

    camper schrieb:

    Wieso nicht einfach

    using std::get;
    

    genauso wie das für std::swap gemacht wird?

    Ich danke dir!!!

    Es klappt wirklich gut für std::get und xsp::get...

    Allerdings weiß ich noch nicht, wie ich es mit dem
    std::tuple_element bzw. xsp::tuple_element
    hinkriege, da es ja eine class/struct ist.

    error: 'tuple_element' is already declared in this scope

    decltype of get anwenden? Oder evtl. ein eigenes tuple_element-Template

    template <std::size_t, typename > struct tuple_element;
    template<std::size_t I, typename... T> struct tuple_element<I, std::tuple<T...>> : std::tuple_element<I, std::tuple<T...>> {};
    template<std::size_t I, typename... T> struct tuple_element<I, xsp::tuple<T...>> : xsp::tuple_element<I, xsp::tuple<T...>> {};
    

Anmelden zum Antworten