2017-10-06 165 views
0

我有一個可變參數模板功能使用包裝對象爲具有可變參數模板和參考參數

template<typename ...ARGS> 
inline void ReadStream::decode(ARGS&...args) { 
    internalDecode(args...); 
} 

template<typename T, typename ...ARGS> 
inline void ReadStream::internalDecode(T &head, ARGS&...args) { 
    read(head); 
    internalDecode(args...); 
} 

    inline void ReadStream::internalDecode() { 
    } 

這允許右值我寫

int a, b; 
ByteArray c; 
String d 

x.decode(a,b,c,d); 

解壓傳入二進制流成一組變量沒有鍋爐板。

我實現了一個包裝對象「固定大小」,改變在解碼一個特定的變量讀取默認格式/。

template <typename T> 
class FixedSize{ 
    T &value; 
    uint16_t length; 

    public: 

    FixedSize(T &wrapped, uint32_t size): 
     value(wrapped), 
     length(static_cast<uint16_t>(size)){ 
    } 

    template< typename STREAM> 
    void read(STREAM &stream){ 
     stream.readBytes(value, 0, length); 
     value.setLength(length); 
    } 

    }; 

    template<typename T> 
    FixedSize<T> fixedSizeField(T &field, uint32_t length){ 
    return FixedSize<T>(field, length); 
    } 

這在理論上將允許解碼像這樣

主叫
x.decode(a,b,fixedSize(c,16), d); 

然而,通過固定大小()返回的對象現在是一個右值和編譯器不太願意允許這與

在從右值....

因爲右值保持到底層對象的引用類型「固定大小&」的非const引用有效的初始化,這個代碼將實際工作如果編譯器將允許我編譯。實際上,如果我創建一個FixedSize類型的對象,然後將它傳遞給解碼函數,就可以工作。

auto e = fixedSize(c,16) 
x.decode(a,b, e, d) 

我該如何去強制編譯器接受作爲右值返回的包裝器對象?

+0

嘗試使用與&&一個universial參考。 這可能會讓其他情況下的併發症,但可以解決您的問題在這裏。 – Raynigon

回答

1

不要;轉發參數無處不在(採取參數數量& & ......並通過的std ::前進(參數)...),除了在頭,並進行過載。觀察包裝器可能是一個const;所以你可以把它作爲const &並且仍然通過引用修改目標。

而且,你不需要解碼()和internalDecode分開,我看到;只需保留internalDecode()並將其命名爲decode()。

0

基於從Iorro的意見,這是採用通用的引用,轉發和函數重載的工作代碼:

template<typename T, typename ...ARGS> 
inline void ReadStream::decode(T &head, ARGS&&...args) { 
    read(head); 
    decode(std::forward<ARGS>(args)...); 
} 

template<typename T, typename ...ARGS> 
inline void ReadStream::decode(const T &head, ARGS&&...args) { 
    read(head); 
    decode(std::forward<ARGS>(args)...); 
} 

inline void ReadStream::decode() { 
} 

FixedWrapper需要作出常量即

功能
template< typename STREAM> 
void read(STREAM &stream) const { 
    stream.readBytes(value, 0, length); 
    value.setLength(length); 
}  

現在致電

x.decode(a,b,fixedSize(c,16), d); 

這個工程,因爲右值可以傳遞給重載函數取(const的牛逼& ......)和一切編譯和運行。