2014-09-29 16 views
14

Tworzę bibliotekę JSON dla C++ 14 i staram się korzystać z semantyki ruchu w miarę możliwości.Jak poprawnie "uzyskać do przodu" funkcje gettera?

Moja Value klasa ma kilka ustawiające i pobierające że zawsze staram się poruszać, gdy to możliwe:

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); } 

Jak widać z kodu, doskonałe funkcje przekierowania setter jest bardzo łatwe przy użyciu szablonów i uniwersalne odniesienia.

Jak mogę zrobić to samo dla funkcji gettera? Jestem prawie pewien, że muszę użyć szablonu typu return, ale nie jestem pewien, jak zreplikować ref-qualifiers i const-correctness.

+1

Kwalifikatory refleksu są dla mnie bezużyteczne. – Rapptz

+0

@Rapptz: Właśnie o to pytam. Używam ref-qualifiers, ponieważ nie jestem pewien, jak wyrazić ten sam kod przy użyciu szablonów (do "perfect-forward" typów zwrotów i upewnij się, że "ta" stała-poprawność jest zachowana). –

+0

@VittorioRomeo: Być może zamierzałeś przejść z 'hObj',' hArr' i 'hStr' w funkcji' && '? –

Odpowiedz

4

Ponieważ nie można szablonować na kwalifikatorach ref i stałej członków, smutną odpowiedzią jest to, że nie można. Musisz je zapisać.

2

To nie jest tak jak szablony C++, ale działa.

#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) 
Powiązane problemy