Betrachten Sie das folgende Beispiel:Trailing Rückgabetyp, Declval und Referenz Qualifier: Können sie zusammenarbeiten?
#include <utility>
struct A { void f() {} };
struct B { void f() & {} };
struct C { void f() && {} };
template<typename T>
auto f() -> decltype(std::declval<T>().f())
{}
int main() {
f<A>();
// f<B>(); // (*)
f<C>();
}
Wenn mit B
(Linie (*)
) aufgerufen, wird der Code kompiliert nicht mehr für std::declval
wandelt T
zu rvalue Referenztyp im konkreten Fall.
Wenn wir es leicht, als es ändern folgt, haben wir das entgegengesetzte Problem:
// ...
template<typename T>
auto f() -> decltype(std::declval<T&>().f())
{}
// ...
int main() {
f<A>();
f<B>();
// f<C>(); // (*)
}
Jetzt Linie bei (*)
nicht für std::declval
wandelt den Typ Lvalue Referenztyp im konkreten Fall arbeiten.
Gibt es eine Möglichkeit, einen Ausdruck zu definieren, der den Typ T
akzeptiert, wenn er eine Elementfunktion f
hat, egal, was ist sein Referenzqualifikator?
Ich habe keinen realen Fall, in dem ich das verwenden würde, und ich kann kein wirkliches Beispiel für die Verwendung machen.
Diese Frage ist der Neugierde, nichts mehr.
Ich verstehe, dass es einen Grund gibt, wenn der Ref-Qualifier da ist und ich nicht versuchen sollte, das Design der Klasse zu brechen.
Wie wäre es 'decltype (& T :: f)'? – Brian
Funktioniert nicht für überladene 'f' – krzaq
@Brian Nun, es würde in diesem minimalen Beispiel funktionieren, aber es funktioniert nicht, wenn Sie Argumente in der _invokation_ verwenden müssen. – skypjack