So leiten Sie den Rückgabetyp einer Funktion ab, die eine Referenz als Parameter akzeptiert
-
21-12-2019 - |
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();
}
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&>()