2014-10-12 2 views
1

у меня есть, например, класс-оболочка:Совершенная пересылка для классов-оболочек

template <typename T> 
struct Wrapper { 
    T t; 
}; 

и некоторые прокси-класс, который принимает что-то делает с T:

template <typename T> 
struct Proxy { 
    T t; 
    void operator()() const {/* .... */} 
} 

Теперь есть для удобства метод, который создает прокси, и я написал перегруженный его для ссылки на l- и r-значение:

template <typename T> 
Proxy<const T &> createProxy(const Wrapper<T> &w) {return {w.t};} 

template <typename T> 
Proxy<T> createProxy(Wrapper<T> &&w) {return {std::move(w.t)};} 

Это, конечно, только урезанный код, который я хотел использовать, но, чтобы сделать все более удобным для чтения, я хочу использовать некоторую идеальные пересылки магию, что приводит к меньшему количеству коды делает все немного более удобное для чтения:

template <typename Wrapper> 
Proxy</* ??? */> createProxy(Wrapper &&w) { /* ??? */ } 

Так вопрос в том, как я могу вычесть тип l- или r-значения члена типа l- или r-значения?

+0

Я не уверен, что вы пытаясь спросить (и тем более, почему вы только обходите это в течение последних 1 до не более 3 абзацев). – Deduplicator

ответ

2

std::forward<Wrapper>(w).t имеет ту же категорию стоимости как w, поэтому все, что вам нужно сделать, это возвращать Proxy с && вырезаны из decltype((std::forward<Wrapper>(w).t)):

template <typename T> 
struct remove_rvalue_reference { 
    using type = T; 
}; 

template <typename T> 
struct remove_rvalue_reference<T&&> { 
    using type = T; 
}; 

template <typename T> 
using remove_rvalue_reference_t = typename remove_rvalue_reference<T>::type; 

template <typename Wrapper> 
auto createProxy(Wrapper&& w) -> 
    Proxy<remove_rvalue_reference_t<decltype((std::forward<Wrapper>(w).t))>> { 
    return {std::forward<Wrapper>(w).t}; 
} 

Demo at Coliru

+0

'std :: remove_rvalue_reference' делает то же самое, что и вышеприведенное право? – user1447257

+0

@ user1447257 Если бы * был * a 'std :: remove_rvalue_reference', это то, что он сделал бы. Там ['std :: remove_reference'] (http://en.cppreference.com/w/cpp/types/remove_reference) и [' std :: add_rvalue_reference'] (http://en.cppreference.com/w/cpp/types/add_reference), но не 'remove_rvalue_reference'. – Casey

+0

Ах да, только что узнал, что я неправильно понял документ. В любом случае, спасибо! – user1447257

 Смежные вопросы

  • Нет связанных вопросов^_^