den folgenden Codeausschnitt Bitte beachten Sie:Überlastung der Plus-Operator für einen Satz von Klassen
template<class E>
class vector_expression
{};
template<class Tuple>
class vector
: public vector_expression<vector<Tuple>>
{};
template<class E1, class E2, class BinaryOperation>
class vector_binary_operation
: public vector_expression<vector_binary_operation<E1, E2, BinaryOperation>>
{
public:
vector_binary_operation(E1&& e1, E2&& e2, BinaryOperation op)
: m_e1(e1), m_e2(e2),
m_op(op)
{}
private:
E1 m_e1;
E2 m_e2;
BinaryOperation m_op;
};
template<class E1, class E2>
vector_binary_operation<E1, E2, std::plus<>> operator+(E1&& e1, E2&& e2) {
return{ std::forward<E1>(e1), std::forward<E2>(e2), std::plus<>{} };
}
Der obige Code dass vector_binary_operation
speichert Verweise auf Objekte mit Namen und macht Kopien für Provisorien gewährleistet. Das Problem ist die Schnittstelle von operator+
, weil es tatsächlich diesen Operator für jeden Typ definiert. Was muss ich ändern, wenn ich die Funktionalität beibehalten möchte, aber nur den Operator für Typen definieren möchte, die von vector_expression
abgeleitet sind?
Die Initialisiererliste in Ihrem Konstruktor sollte besser sein: 'm_e1 (std vorwärts (e1) ::), m_e2 (std :: vorwärts (e2)), m_op (std :: move (op)) '. Sonst bricht man die perfect-forwarding Kette. –
davidhigh
@davidhigh Ja, du hast Recht. Ich habe den Code von der anderen Frage kopiert, und dort waren die Parameter "e1" und "e2" konstante Referenzen. Danke, dass du das notiert hast. – 0xbadf00d
Nein, ich liege falsch. Ich hätte Recht, wenn der Konstruktor eine Funktionsvorlage wäre, etwa so etwas wie "Vorlage Vektor_Binäroperation (E1 _ && e1, E2 _ && e2, BinäreOperation op)". Übrigens, das ist wahrscheinlich das, was Sie beabsichtigt haben, als Sie die '&&' verwendet haben. Weitere Informationen finden Sie unter [hier] (https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers) –
davidhigh