C++ 具有boost::any等泛型类型的std::tuple
亲爱的程序员们: 下面的代码让我有些头疼。它尝试向元组添加一个“通用”对象(=可以从任何对象构造的对象),然后复制该元组C++ 具有boost::any等泛型类型的std::tuple,c++,c++11,C++,C++11,亲爱的程序员们: 下面的代码让我有些头疼。它尝试向元组添加一个“通用”对象(=可以从任何对象构造的对象),然后复制该元组 #include <tuple> #include <iostream> #include <typeinfo> struct anything { anything() {} anything(const anything&) {
#include <tuple>
#include <iostream>
#include <typeinfo>
struct anything
{
anything()
{}
anything(const anything&)
{
std::cout << "Called copy c'tor" << std::endl;
}
template<class T>
anything(T arg)
{
std::cout << "Called c'tor with with argument of type " << typeid(arg).name() << std::endl;
// new T(arg); // causes stack overflow
}
};
int main()
{
std::tuple<anything> t;
//
std::cout << "Copy constructing t2, expecting copy c'tor to be called." << std::endl;
std::tuple<anything> t2(t);
return 0;
}
#包括
#包括
#包括
构造任何东西
{
任何事
{}
任何东西(常数任何东西&)
{
std::cout键类型;
升压::信号2::信号
Boost信号在调用slot函数之前在内部将参数包装在一个tuple中,这最终会导致堆栈溢出,因为tuple c'tor使用tuple作为参数调用any c'tor,而any c'tor则使用'any of tuple'调用tuple c'tor,依此类推……如果您查看t你会注意到的
_Tuple_val<_This> _Myfirst; // the stored element
...
template<class _This2,
class... _Rest2,
class = typename _Tuple_enable<tuple<_This2, _Rest2...>, _Myt>::type>
explicit tuple(_This2&& _This_arg, _Rest2&&... _Rest_arg)
: _Mybase(_STD forward<_Rest2>(_Rest_arg)...),
_Myfirst(_STD forward<_This2>(_This_arg))
{ // construct from one or more moved elements
}
UPD 根据标准std::tuple提供以下构造函数:
template <class... UTypes>
explicit constexpr tuple(const Types&...);
template <class... UTypes>
constexpr tuple(const tuple<UTypes...>&);
模板
显式constexpr元组(const类型&…);
模板
constexpr元组(consttuple&);
显然,您的模板构造函数比元组的复制构造函数更匹配。让我们看看重载解析:
std::tuple<anything> t2(t);
自<代码>(3)起,此功能就开始工作是根据是可转换的
来指定的,它在显式
转换时返回false。但是,这目前被认为是一个缺陷,将来可能会发生变化-因为毕竟,我们在这里显式构造每个方面,所以仍然应该考虑显式
构造函数!
一旦发生这种情况,就直接复制构造而言,您就有点运气不佳。您必须为元组禁用任何构造函数?这似乎…不太好。但是在这种情况下,将该构造函数标记为显式对于复制初始化仍然有效:
std::tuple<anything> t2 = t;
std::tuple t2=t;
由于上述同样的缺陷,现在即使没有标记任何东西构造函数explicit
,它也能工作。让模板构造函数explicit
谢谢你的回答。我接受了Barry的,因为它更完整。至少可以说,std::tuple的这种行为似乎不直观。std::tuple是否应该有一个复制构造函数重载来引用non-const:tuple(tuple&other),以确保std::tuple t2(t);行生成一个副本?
template <class... UTypes>
explicit constexpr tuple(const Types&...);
template <class... UTypes>
constexpr tuple(const tuple<UTypes...>&);
std::tuple<anything> t2(t);
explicit tuple( const Types&... args ); // (2) with Types = [anything]
template< class... UTypes >
explicit tuple( UTypes&&... args ); // (3) with UTypes = [std::tuple<anything>&]
tuple( const tuple& other ) = default; // (8)
tuple(const anything& ); // (2)
tuple(std::tuple<anything>& ); // (3)
tuple(std::tuple<anything> const& ); // (8)
template<class T>
explicit anything(T arg) { ... }
std::tuple<anything> t2 = t;