Frage

Ich versuche, den Rückgabetyp einer Funktion abzuleiten und ihn als Rückgabetyp einer Mitgliedsfunktion zu verwenden.Dazu verwende ich einen Decltype-Ausdruck.Aber alle meine Versuche scheitern beim Kompilieren, wenn die angegebene Funktion eine Referenz als Argument akzeptiert:

  • Ich kann im decltype-Ausdruck keine Mitgliedsvariablen meiner Klasse verwenden, da sich der Compiler darüber beschwert, dass es keine solchen Mitglieder gibt (siehe func1 unten)
  • Ich kann für den Funktionsparameter kein temporäres Element verwenden, da die Funktion eine Referenz benötigt und Sie keine nicht konstante L-Wert-Referenz an ein temporäres Element binden können (siehe func2 unten)

Ich habe auch verschiedene Casting-Operatoren ausprobiert, um die Referenz temporär zu machen, aber nichts scheint ein gültiger Ausdruck zu sein.

Hier ein Codebeispiel:

template<typename data_type, typename functor_type>
class MyClass
{
public:
    auto func1() -> decltype(functor_type::process(this->m_data)) // <--
    {
        return functor_type::process(m_data);
    }

    auto func2() -> decltype(functor_type::process(data_type{})) // <--
    {
        return functor_type::process(m_data);
    }

private:
    data_type m_data;
};

struct Functor
{
    static int process(int& a) { return a; }
};

int main()
{
    MyClass<int, Functor> m;
    int b = m.func1();
    int c = m.func2();
}
War es hilfreich?

Lösung

Der erste Fehler schlägt fehl, da die Klasse in der Funktionsdeklaration nicht vollständig ist, wie dies in den Funktionskörpern der Member der Fall ist. Daher können Sie nur Member verwenden, die bereits deklariert wurden.

Für den zweiten sorgt die Standardbibliothek declval, eine Funktionsvorlage, die so deklariert wurde, dass sie ihren Vorlagenparametertyp zurückgibt.Sie können dies in nicht ausgewerteten Kontexten verwenden, wenn Sie einen Ausdruck eines bestimmten Typs benötigen.

Die folgende Version sollte also funktionieren:

#include <utility> // for declval

template<typename data_type, typename functor_type>
class MyClass
{
private:
    // Declare this before `func1`
    data_type m_data;

public:
    // Use the already declared member variable
    auto func1() -> decltype(functor_type::process(m_data))
    {
        return functor_type::process(m_data);
    }

    // Or use `declval` to get an expression with the required reference type
    auto func2() -> decltype(functor_type::process(std::declval<data_type&>()))
    {
        return functor_type::process(m_data);
    }
};    

Andere Tipps

Ich glaube, Sie suchen std::declval<data_type&>()

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