2016-11-24 165 views
4

我最近發現使用std::tuple<>只是一個元素的問題。我創建了一個擦除類型並保留N個引用計數對象的類。但是,如果引用計數對象是std::tuple<>中唯一的對象,則不會保留。一個std :: shared_ptr <>的std :: tuple <>不起作用?

我做錯了什麼?

class token { 
public: 
    template<typename... Types> 
    token(Types... types) : _self(std::make_shared<const std::tuple<Types...>>(std::make_tuple(std::move(types)...))) {} 

    // Why do I need this special version of the constructor? 
    // Uncomment and the code will work! 
    //template<typename T> 
    //token(T t) : _self(std::make_shared<const T>(std::move(t))) {} 
private: 
    std::shared_ptr<const void> _self; 
}; 

例(在Xcode 8.0測試):

token make_token() { 
    std::shared_ptr<int> shared(new int(), [](int* i) { 
    // Called immediately if using only tuple constructor! 
    }); 
    return token(shared); 
} 
token my_token = make_token(); // std::shared_ptr<> is already gone! 
+0

在gcc中工作,但不在鐺 – Danh

+0

@Danh謝謝!那麼我不會發瘋。我向誰彙報這件事? –

+0

似乎固定在主幹上(http://melpon.org/wandbox/permlink/8YUeWAcj3PzyWphs)。 –

回答

1

從我的角度來看,你的代碼應該做工精細,MSVC和gcc似乎this snippet同意我。從T.C.評論,這看上去就像真正的問題鏗鏘並固定在鐺主幹

作爲一種解決方法,現在,我建議這種方法,(special_decay_tcppreference取):

#include <iostream> 
#include <tuple> 
#include <memory> 

template <class T> 
struct unwrap_refwrapper 
{ 
    using type = T; 
}; 

template <class T> 
struct unwrap_refwrapper<std::reference_wrapper<T>> 
{ 
    using type = T&; 
}; 

template <class T> 
using special_decay_t = typename unwrap_refwrapper<typename std::decay<T>::type>::type; 

class token { 
public: 
    template<typename... Types> 
    token(Types&&... types) : _self(std::make_shared<std::tuple<special_decay_t<Types>...>>(std::forward<Types>(types)...)) {} 

private: 
    std::shared_ptr<void> _self; 
}; 


token make_token() { 
    return token(std::shared_ptr<int>(new int(), [](int* i) { 
    std::cout << "freed\n"; 
    delete i; 
    })); 
} 

int main() 
{ 
    token my_token = make_token(); 
    std::cout << __LINE__ << '\n'; 
} 

看到這個demo

相關問題