2014-09-29 5 views
14

Sto creando una libreria JSON per C++ 14 e sto cercando di utilizzare la semantica del movimento ogni volta che è possibile.Come eseguire correttamente le funzioni getter "perfezionate in avanti"?

La mia classe Value ha diverse setter e getter che da sempre cercano di muoversi quando possibile:

template<class T> void setObj(T&& x) { type = Obj; hObj.init(forward<T>(x)); } 
template<class T> void setArr(T&& x) { type = Arr; hArr.init(forward<T>(x)); } 
template<class T> void setStr(T&& x) { type = Str; hStr.init(forward<T>(x)); } 

auto& getObj() & noexcept    { assert(is<Obj>()); return hObj; } 
auto& getArr() & noexcept    { assert(is<Arr>()); return hArr; } 
auto& getStr() & noexcept    { assert(is<Str>()); return hStr; } 
const auto& getObj() const& noexcept { assert(is<Obj>()); return hObj; } 
const auto& getArr() const& noexcept { assert(is<Arr>()); return hArr; } 
const auto& getStr() const& noexcept { assert(is<Str>()); return hStr; } 
auto getObj() && noexcept    { assert(is<Obj>()); return move(hObj); } 
auto getArr() && noexcept    { assert(is<Arr>()); return move(hArr); } 
auto getStr() && noexcept    { assert(is<Str>()); return move(hStr); } 

Come si può vedere dal codice, perfetti funzioni di inoltro setter è abbastanza facile utilizzando i modelli e riferimenti universali.

Come posso fare lo stesso per le funzioni getter? Sono abbastanza sicuro di dover utilizzare un tipo di restituzione del modello, ma non sono sicuro di come replicare i qualificatori del ref e la cost-correctness.

+1

Le qualificazioni di ref mi sembrano inutili qui. – Rapptz

+0

@Rapptz: Questo è il punto della domanda. Sto usando le qualifiche di ref perché non sono sicuro di come esprimere lo stesso codice usando i template (per restituire perfettamente i tipi di ritorno e assicurarmi che sia mantenuta la costanza di 'this'). –

+0

@VittorioRomeo: Forse intendevi spostarti da 'hObj',' hArr' e 'hStr' nelle funzioni' && '? –

risposta

4

Poiché non è possibile creare un modello sui qualificatori di riferimento e sulla costitabilità dei membri, la risposta triste è che non è possibile. Devi scriverli.

2

Questo non è come i modelli C++ ma fa il lavoro.

#define GETTERS(V) \ 
      V(Obj) \ 
      V(Arr) \ 
      V(Str) 

    #define VISIT(X) \ 
      auto &get ## X() & noexcept { assert(is<X>()); return h ## Obj; } \ 
      const auto &get ## X() const& noexcept { assert(is<X>()); return h ## Obj; } \ 
      auto &get ## X() && noexcept { assert(is<X>()); return std::move(h ## Obj); } 


    GETTERS(VISIT) 
Problemi correlati