2016-06-25 13 views
1

Ich versuche, einige generische Programmierung zu tun, in denen ich eine Instanz von einigen Strukturen (die in irgendeiner Weise registriert wurde) und führt eine spezielle Operation mit jedem einer Teilmenge seiner Mitglieder.Wie leitet man ein Strukturelement perfekt weiter?

Ich habe eine Eigenschaft, die ein bisschen wie folgt aussieht:

template <typename S> 
struct visitable<S, std::enable_if_t<is_visitable<S>::value>> { 
    template <typename V, typename T> 
    static void apply_visitor(V && v, T && t) { 
    v(t.*(get_registered_member_ptr<S>::value)); 
    } 
} 

template <typename V, typename S> 
void apply_visitor(V && v, S && s) { 
    visitable<std::remove_cv_t<std::remove_reference_t<S>>>::apply_visitor(std::forward<V>(v), std::forward<S>(s)); 
} 

Dies ist eine Vereinfachung, sind tatsächlich mehrere Mitglied Zeiger zu gehen, und der Besucher wird mehrmals angewendet werden. Aber es kommt auf das Herz des Problems.

In diesem Code wird T der gleiche Typ wie S sein, aber mit einigen CV/Referenzqualifikatoren, die ich verwende, damit ich nicht alle Überlastungen manuell eingeben muss. Ich möchte den Besucher mit dem gleichen Werttyp wie der Ausdruck aufrufen, der vom Benutzer übergeben wurde.

Aber wenn ich den Zeiger auf Mitglied anwenden möchte, habe ich ein Problem, weil ich nicht mehr verwenden kann, um die richtigen Qualifikationsmerkmale zu erhalten, wenn ich es an den Besucher übergebe.

Gibt es eine ausgefallene Version von std::forward, die das tun kann, wie, wenden Sie die CV-und Referenzqualifikatoren der ersten Vorlage Parameter auf den zweiten Parameter und geben Sie mir das Ergebnis? Oder soll ich einfach eins machen? Oder gibt es dafür eine bessere Sprache?

+0

Ich würde nicht erwarten, gut geschrieben und entworfen C++ - Code, um 'remove_cv_t 'in einem so extremen Ausmaß zu verwenden. Das sieht nach einem Designproblem aus. –

+0

@SamVarshavchik: Es ist nur weil, wenn der Typ registriert ist, hat es keine CV oder Ref-Qualifikationsmerkmale, aber wenn es über die perfekte Weiterleitung übergeben wird, tut es. Wenn ich 'remove_cv_t' und so nicht habe, dann wird entweder die Template-Spezialisierung nicht gefunden oder du musst sie 5 oder 6 mal extra registrieren. –

Antwort

1
std::forward<V>(v)(std::forward<T>(t).*(get_registered_member_ptr<S>::value)) 

Sollte der Trick tun.

+0

Ahhh ... Ich sehe, also wird der Operator '. *' Mit rvalue-Referenzen das Richtige tun. Das habe ich nicht bemerkt. Vielen Dank. –

+0

@chris Ich weiß, '.' wird das Richtige tun. Ich habe nicht überprüft, dass '. *' Würde, aber ich nehme die Kompetenz von Standardautoren an. – Yakk

Verwandte Themen