2016-11-24 170 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

相关问题