2017-04-16 2 views
0

Bitte beachten Sie den folgenden Code ein:Shop eine konstante Referenz, wann immer ein L-Wert übergeben wird, und eine Kopie, wenn ein R-Wert übergeben wird

template<typename T> 
class scalar_reference 
{ 
public: 
    template<typename U> 
    scalar_reference(U&& value) 
     : m_value(std::forward<U>(value)) 
    {} 

    T const& operator()() const { return m_value; } 

private: 
    T m_value; 
}; 

template<typename T> 
scalar_reference<T> foo(T&& value) { 
    return scalar_reference<T>{ std::forward<T>(value) }; 
} 

Die Absicht ist, dass die zurück scalar_reference durch foo eine konstante Referenz hält an a std::decay_t<T> wann immer foo mit einem Lvalue und einer Kopie aufgerufen wird, wenn foo mit einem Rvalue aufgerufen wird.

Der obige Code funktioniert nicht. Wenn wir beispielsweise int x; foo(x) anrufen, wird Tint& sein, und operator() wird auch int& zurückgeben (da der const Qualifier keine Auswirkung auf einen Referenztyp hat).

Also, wie müssen wir den Code ändern?

+0

Warum nicht einfach zwei Konstruktoren deklarieren; eine nimmt eine lvalue-Referenz und eine eine rvalue-Referenz? – Daniel

Antwort

2

Ist das einzige Problem der Rückgabetyp operator()? Wenn ja, können Sie die Referenz zuerst löschen:

std::decay_t<T> const& operator()() const { return m_value; } 
+0

Ja, Sie könnten Recht haben. Ich habe nicht bemerkt, dass dies das einzige Problem ist. – 0xbadf00d

Verwandte Themen