2012-07-27 23 views
1

make_pair可以創建對而不提及類型。我想爲我的班級使用相同的技巧,但它繼承自boost :: noncopyable,所以這不會編譯:make_pair類似於不可複製類的技巧

template<class Iter> 
struct bit_writer : boost:noncopyable 
{ 
    Iter iter; 
    bit_writer(Iter iter) 
    : iter(iter) 
    {} 
}; 

template<class Iter> 
bit_writer<Iter> make_bit_writer(Iter iter) 
{ 
    return bit_writer<Iter>(iter); 
} 
vector<char> vec; 
auto w = make_bit_writer(vec); 

任何替代方案?我試圖讓make_bit_writer成爲朋友,然後用盡想法。

+5

假設你不想通過某種指針(最好是智能指針)返回,是否有可能使bit_writer成爲移動類?實際上,你基本上是告訴編譯器創建一個臨時的並返回它,但臨時的既不能被移動也不能被複制。 – 2012-07-27 21:07:16

+4

C++ 11是一個選項嗎? – Flexo 2012-07-27 21:08:06

+0

您是否嘗試過宏? :-D(只是在開玩笑...) – Mehrdad 2012-07-27 21:23:13

回答

4

如果你有C++ 11,你可以做到這一點使用是這樣的:

#include <functional> 
#include <utility> 
#include <type_traits> 

struct noncopyable_but_still_moveable { 
    noncopyable_but_still_moveable(const noncopyable_but_still_moveable&) = delete; 
    noncopyable_but_still_moveable(noncopyable_but_still_moveable&&) = default; 
    noncopyable_but_still_moveable() = default; 
    noncopyable_but_still_moveable& operator=(const noncopyable_but_still_moveable&) = default; 
    noncopyable_but_still_moveable& operator=(noncopyable_but_still_moveable&&) = default; 
}; 

template <typename T> 
struct test : noncopyable_but_still_moveable { 
    test(T) {} 
    // the rest is irrelevant 
}; 

template <typename T> 
test<T> make_test(T&& val) { 
    return test<typename std::remove_reference<T>::type>(std::forward<T>(val)); 
} 

int main() { 
    auto && w = make_test(0); 
} 

請注意,我把它換成boost::noncopyable與有缺失的拷貝構造函數類型。這是C++ 11的一種不可複製的方法,因爲boost類也不可移動。當然,你可以把它放在課堂本身,而不是繼承。

沒有C++ 11,你會想用類似Boost move來模擬這些語義。

+0

我把你的最後一行改爲 auto && w = make_test(0); 所以我可以在w上調用非const成員。變更安全嗎? – 2012-07-31 18:50:02

+0

update:auto &&崩潰 – 2012-07-31 19:01:29

+0

@BrunoMartinez'const auto&w'應該可以工作。 – Flexo 2012-07-31 19:10:13

2

您將需要C++ 11並更新您的類的移動語義。對於所提出的問題沒有其他解決方案。

class test { 
public: 
    test(test&&); 
    // stuff 
}; 
test make_test(...) { 
    return test(...); 
} 
int main() { 
    // Both valid: 
    auto p = make_test(...); 
    auto&& p2 = make_test(...); 
}