Ich würde einfach zu const Referenzen bleiben, wie von der vorherigen Antwort erläutert. Aber um zu verdeutlichen, warum Ihr Code nicht funktioniert, gilt die perfekte Weiterleitung nur dann, wenn Sie einen rvalue-Verweis auf einen cv-unqualifizierten Template-Parameter verwenden. In juristischer Hinsicht hat es nur T&&
sein, wo T
ein Funktions-Template-Parameter ist:
template<class T>
void ForwardMe(T&& t)
{
DoSomething(std::forward<T>(t));
}
Die Idee ist, dass der Compiler in der Lage sein wird, T
als type&
abzuleiten, wenn ein L-Wert übergeben (so die Funktionssignatur wird void ForwardMe(type&)
wegen der kollabierenden Referenzregeln) oder nur type
im Falle von rvalues (Signatur wird void ForwardMe(type&&)
).
In Ihrem Beispiel haben Sie so etwas wie:
template<int N, template<int> class T>
void ForwardMe(T<N>&& t)
{
// ...
}
Dies als Sie erwartet hatte nicht funktioniert, weil der Compiler nicht T
ableiten kann ein Hinweis auf etwas zu sein, so dass Sie nicht perfekt machen können Weiterleitung Der Funktionsparameter t
stimmt daher nur mit rvalue-Referenzen überein.
Da const-Referenzen an Provisorien binden können, lösen Sie im obigen Beispiel const T<N>&
, um Ihre Probleme zu lösen. Aber wenn Sie wirklich beide L-Wert und R-Wert-Eingänge unterstützen wollen (weil Sie bewegen Semantik haben, wo zutreffend), haben Sie zwei Möglichkeiten:
- schreiben Überlastungen für alle 4 Permutationen: L-Wert * L-Wert, L-Wert * R-Wert, rvalue * lvalue, rvalue * rvalue.
- Schreiben Sie eine generische Funktionsschablone und verwenden Sie SFINAE, um die Eingabetypen zu begrenzen.
Letzteres wäre so etwas wie:
#include <type_traits>
template<class L, class R>
struct MatrixMulResult_helper;
template<int n, int m, int k, template<int, int> class T>
struct MatrixMulResult_helper<T<n, m>, T<m, k>> { using type = T<n, k>; };
template<class L, class R>
using MatrixMulResult = typename MatrixMulResult_helper<L, R>::type;
template<class L, class R>
MatrixMulResult<std::decay_t<L>, std::decay_t<R>>
operator*(L&& lhs, R&& rhs)
{
// ...
}
Der Compiler ist jetzt frei L
und R
als Bezugnahmen abzuleiten. MatrixMulResult<>
stellt sicher, dass diese Funktion nur dann definiert ist, wenn (die verfallenen Typen von) L
und R
jeweils die Form T<n,m>
und T<m,k>
haben. Es gibt eine T<n,k>
zurück.
"Funktioniert nicht" bedeutet, dass Sie einen Compilerfehler erhalten? Wenn ja, was ist dieser Fehler? – tadman
Tippfehler? Sie beginnen mit ' vu1p3n0x
@tadmad: siehe die Bearbeitung, @ vu1p3n0x: Danke, behoben –