C++ 为什么调用move构造函数和move赋值运算符而不是copy?
可能重复: 我有存储std::unique\u ptr adapted boost::any所需的这些类:C++ 为什么调用move构造函数和move赋值运算符而不是copy?,c++,boost,stl,c++11,C++,Boost,Stl,C++11,可能重复: 我有存储std::unique\u ptr adapted boost::any所需的这些类: class any { public: any() : content(0) { } any(any const&) = delete; any(any && other) : content(other.content) { content = 0; } template<typename Va
class any
{
public:
any()
: content(0)
{
}
any(any const&) = delete;
any(any && other)
: content(other.content)
{
content = 0;
}
template<typename ValueType>
any(ValueType const& value)
: content(new holder<ValueType>(value))
{
}
template<typename ValueType>
any(ValueType && value,
typename std::enable_if<!std::is_lvalue_reference<ValueType>::value,
void>::type* = 0)
: content(new holder<ValueType>(std::move(value)))
{
}
~any()
{
delete content;
}
public: // modifiers
any & swap(any & rhs)
{
std::swap(content, rhs.content);
return *this;
}
any & operator=(const any &) = delete;
any & operator=(any && rhs)
{
return swap(rhs);
}
template<typename ValueType>
any & operator=(ValueType const& rhs)
{
any(rhs).swap(*this);
return *this;
}
template<typename ValueType>
typename std::enable_if<!std::is_lvalue_reference<ValueType>::value,
any&>::type operator=(ValueType && rhs)
{
any(std::move(rhs)).swap(*this);
return *this;
}
public: // queries
bool empty() const
{
return !content;
}
const std::type_info & type() const
{
return content ? content->type() : typeid(void);
}
private: // types
class placeholder
{
public: // structors
virtual ~placeholder()
{
}
public: // queries
virtual const std::type_info & type() const = 0;
};
template<typename ValueType>
class holder : public placeholder
{
public: // structors
template <class T>
holder(T && value)
: held(std::forward<T>(value))
{
}
holder & operator=(const holder &) = delete;
public: // queries
virtual const std::type_info & type() const
{
return typeid(ValueType);
}
public:
ValueType held;
};
private: // representation
template<typename ValueType>
friend ValueType * any_cast(any *);
template<typename ValueType>
friend ValueType * unsafe_any_cast(any *);
placeholder * content;
};
还有这个:
std::map<int, int> map({{1,1},{2,2}});
any b(map);
std::cout << map.size() << std::endl; // displays 0
令我恐惧的是,在gdb下,我注意到在构造和分配b时甚至从map调用了move构造函数和move assignment操作符,尽管我没有用std::move标记a,而且它不是临时的。有人能解释一下原因吗?我的第一个答案是错的。在再次阅读了非常不可读的代码之后,我发现您显式地提供了一个move和default构造函数,但没有复制构造函数。如果一个类有两个用户定义的构造函数,编译器将不会为该类生成任何其他构造函数。因此,您的类没有复制构造函数 编辑:那么,回到我最初的答案,由您的评论提示。§12.8/7[类别副本]规定: 从未实例化成员函数模板以执行复制 将类对象转换为其类类型的对象。[示例:
struct S {
template<typename T> S(T);
template<typename T> S(T&&);
S();
};
S f();
const S g;
void h() {
S a( f() ); // does not instantiate member template;
// uses the implicitly generated move
constructor S a(g); // does not instantiate the member template;
// uses the implicitly generated copy constructor
}
-[结束示例]
由于您的复制构造函数是成员模板,但您的移动构造函数不是,因此此处选择后者。在这方面,您的案例与示例不同。一些一致的缩进将非常有用。我编辑了boost::any hack供后人使用。未选择此构造函数,正如在我的编辑中所解释的。移动模板构造函数被调用,而不是任何移动构造函数,也从地图中检查构造,它为什么被移动?嗯,那我就不知道了。也许你可以提供一个最小的程序,这样我们可以在本地重现你的问题?@user1095108:如果你需要帮助,你必须在你的问题上做一些工作。这包括提供一个程序,我可以复制/粘贴,然后编译和执行以重现您的问题。另外,您使用的是哪种编译器和boost版本?正确的答案是&&&&&˙是模板函数中的一个包罗万象的参数,显然也是构造函数。请参阅以获取解决方案。
struct S {
template<typename T> S(T);
template<typename T> S(T&&);
S();
};
S f();
const S g;
void h() {
S a( f() ); // does not instantiate member template;
// uses the implicitly generated move
constructor S a(g); // does not instantiate the member template;
// uses the implicitly generated copy constructor
}