Frage

Boost-Lambda erlaubt abgeleitete Rückgabetyp mit ret<T> Vorlage zu überschreiben. Ich habe für gleichwertig in Phoenix versucht suchen, konnte aber nicht finden.

Gibt es ein Äquivalent in Phoenix? Ich weiß, wie meine eigenen Ersatz zu machen, aber ich möchte lieber nicht. danke

War es hilfreich?

Lösung

Rewrite. I den Punkt auf meiner ersten Antwort verpasst (es war spät), lassen Sie mich noch einmal versuchen

Lassen Sie mich einige Exposition für Leute wie mich geben, die Ihren Standpunkt zum ersten Mal verpassen könnte. In boost :: Lambda, wenn Typen Benutzer definierten in Operator Ausdrücke verwendet, hat man die ret <> Funktion außer Kraft zu setzen Rückgabetyp Abzug zu verwenden. Dies liegt daran, dass das Lambda-Rückgabetyp Abzug System nur native unterstützt (und stl? Ich erinnere mich nicht) direkt Typen. Ein kurzes Beispiel:

using namespace boost::lambda;

struct add_t{
    add_t(int i) : i(i) {};
    add_t operator+(const add_t& other) const{
        return add_t(i + other.i);
    }
    int i;
};

(_1 + _2)(add_t(38), add_t(4));           // RETURN TYPE DEDUCTION FAILS
ret<add_t>(_1 + _2)(add_t(38), add_t(4)); // OK

In phoenix allerdings werden keine Hinweise benötigt werden (beachten Sie, dass Literale und nicht-const Provisorien nicht in einer phoenix Argumentliste erscheinen können):

using namespace boost::phoenix;

add_t i(38), j(4);
(_1 + _2)(i, j);    // JUST FINE

Der Abzug System Rückgabetyp ist völlig anders und viel natürlicher in Phoenix; es wird richtig den Rückgabetyp von Operatoren ableiten, die konventionelle Semantik verwenden. Insbesondere sollte der Rückgabetyp den Typ der einer der Operanden übereinstimmt, einen Verweis, Zeiger oder const Zeiger auf eine der Argumenttypen sein, oder ein stl Behälter / container Iterator eines dieser Typen sein. Es gibt einen schönen Schreib aus Phoenix Rückgabetyp Abzug in type_deduction.hpp Header für weitere Details.

So, jetzt lese ich Ihre Frage, wie kann nicht konventionelle Operator Semantik in Phoenix behandelt werden?

Sie sich das folgende seltsame Paar von Typen als Beispiel

struct add_ret_t{
    add_ret_t(int i) : i(i) {};
    int i;
};

struct add_t{
    add_t(int i) : i(i) {};
    add_ret_t operator+(const add_t& other) const{
        return add_ret_t(i + other.i);
    }
    int i;
};

Für lambda, ist das kein Problem, benutzen Sie einfach die ret Funktion:

using namespace boost::lambda;

ret<add_ret_t>(_1 + _2)(add_t(38), add_t(4)); // OK

Aber phoenix kann nicht mit diesem Operator befassen (können Sie es schuld?), Weil der Rückgabetyp nicht auf die Argumente verwendet ist, und es gibt keine Möglichkeit, direkt den Rückgabetyp in Phoenix an. Wenn es ein guter Grund, einen Operator wie diese zu verwenden, könnte ein Fall die Art Abzug System hinzugefügt werden, aber ich kann nicht einen Weg, dies zu tun, ohne Hacking type_deduction.hpp oder Verzweigung einen guten Teils von Phoenix sehen.

Alternativ, dachte ich, ein wenig Hack heraus die Rückgabetypen für bestimmte Operatoren außer Kraft zu setzen. Die result_of_ Operation Template-Strukturen in boost / Geist / home / phoenix / Betreiber / arithmetic.hpp (Zeilen 39-56 Liste der Strukturtypen, auftrieb 1,43) den Typ Abzug auszuführen, wenn sie instanziiert werden und speichern die Ergebnis. Also alles, was benötigt wird, ist es, einige Template Spezialisierungen für das Problem Operationen bereitzustellen, die nur eine typedef Angabe des Rückgabetypen enthalten muss. Beispiel ( Codepad für volle src ):

using namespace boost::phoenix;

namespace boost{ namespace phoenix{

//override add_t addition to give add_ret_t
template <> struct result_of_plus<add_t&, add_t&> { typedef add_ret_t type; };

//override int addition to give char
template <> struct result_of_plus<int&, int&> { typedef char type; };

}}

int main()
{
    add_t i = 1, j = 7;
    std::cout << ((_1 + _2)(i, j)).i << std::endl;

    int k = 51, l = 37;
    std::cout << ((_1 + _2)(k, l)) << std::endl;

    return 0;
}

Dies ist sicherlich kein ret Ersatz, sondern in gewissem Sinne ist es besser, seit seinem global. Wenn es viele Betreiber Überlastung sind, könnte das ganze Reihe von Operationen sein macroed.

Andere Tipps

AFAIK, diese (oder etwas ähnliches) nicht in Phoenix unterstützt. Wenn Sie Ihren Anwendungsfall beschrieben könnte ich Hilfe der Lage sein, though.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top