正在尝试使用c++移动构造函数..并失败
Trying to use c++ move constructor...and fail
当我认为我理解std::move和move构造函数的作用时,我试图编写一些单元测试,实际上是为一些类测试move构造函数。。。
令我惊讶的是,我发现我想不出一种方法来构造真正调用move构造函数的代码。更糟糕的是,我甚至不能在move构造函数的主体中设置断点(在VS2013社区版,调试,64位构建中)。
我想知道这是否是编译器的特性,于是在我的freebsd虚拟机上用clang(3.4.1.)编写了一些小的测试代码。在那里,我也找不到调用move构造函数的方法。
#include <iostream>
#include <stdint.h>
#include <string>
#include <algorithm>
#include <functional>
#include <ctype.h>
#include <locale>
void InPlaceToUpper( std::string& target )
{
std::transform(target.begin(), target.end(), target.begin(), ::toupper);
}
void InPlaceToLower( std::string& target )
{
std::transform(target.begin(), target.end(), target.begin(), ::tolower);
}
std::string ToUpper( const std::string& s )
{
std::string result;
result.resize(s.length());
std::transform(s.begin(), s.end(), result.begin(), ::toupper);
return result;
}
std::string ToLower( const std::string& s)
{
std::string result;
result.resize(s.length());
std::transform(s.begin(), s.end(), result.begin(), ::tolower);
return result;
}
class CFoo
{
std::string m_value;
public:
CFoo()
: m_value()
{
std::cout << "CFoo() called." << std::endl;
}
CFoo(const char *value)
: m_value(value)
{
std::cout << "CFoo(const char *) called." << std::endl;
}
CFoo(const std::string& value )
: m_value(value)
{
std::cout << "CFoo(const std::string&) called." << std::endl;
}
CFoo(const CFoo& other )
: m_value(other.m_value)
{
std::cout << "CFoo() copy constructor called." << std::endl;
}
CFoo(CFoo&& other )
: m_value(std::move(other.m_value))
{
std::cout << "CFoo() move constructor called." << std::endl;
std::cout << "other.m_value = " << other.m_value.c_str() << std::endl;
}
~CFoo()
{
std::cout << "~CFoo() called." << std::endl;
}
const CFoo& operator=( const CFoo& other )
{
std::cout << "CFoo copy assignment operator called." << std::endl;
if( &other != this )
{
m_value = other.m_value;
}
return *this;
}
const CFoo& operator=( CFoo&& other )
{
std::cout << "CFoo move assignment operator called." << std::endl;
if( &other != this )
{
m_value = std::move(other.m_value);
}
return *this;
}
CFoo ToUpper()
{
return CFoo(::ToUpper(m_value));
}
CFoo ToLower()
{
return CFoo(::ToLower(m_value));
}
const char * ToString() const
{
return m_value.c_str();
}
};
int main( int argc, const char *argv[] )
{
{
CFoo foo;
CFoo foo1("Hello World");
CFoo foo2 = CFoo("Hello again World!");
CFoo foo3(CFoo("Bye world"));
CFoo foo4 = CFoo("Bye again world");
CFoo foo5 = foo4.ToUpper();
CFoo foo6 = foo4.ToLower();
foo6 = foo4.ToUpper();
std::cout << "foo4: " << foo4.ToString() << std::endl;
foo6 = CFoo("Well well well");
}
return 0;
}
如果代码没有可能的那么短,我很抱歉。但只有几个地方可以看,即我在main()中调用move构造函数的努力,以及Foo类中各种构造函数的定义。
我知道编译器设置允许关闭RVO之类的功能,但为了在性能感知代码中使用"移动构造函数"功能,应该有一个调用它的经典示例。如果不是这样的话,我可能会决定根本不使用move构造函数。
为了回答这个问题,你可以告诉我我可以在main()中写一行,它调用了CFoo的move构造函数。或者你可以告诉我我做错了什么
std::string支持这样移动吗?也许这就是我的努力失败的原因?
谢谢,提前。
在所有使用move构造函数的尝试中,它都被忽略了,因此例如CFoo foo = CFoo(blah);
只相当于CFoo foo(blah);
,它不需要使用move构造器。这是一件好事,因为编译器正在优化,根本不需要进行任何复制或移动。
要查看正在使用的移动构造函数,请尝试:
CFoo f1;
CFoo f2 = std::move(f1);
这将从右值构造f2
,并且不能省略任何内容,因此将使用move构造函数。
首先,std::string ToUpper(const std::string& s)
中有一个错误,即result
中没有空间。C++算法不会自动增长其目标容器。您必须自己分配空间,或者使用插入器适配器。
要腾出空间,例如:
result.resize(s.length());
之后,移动分配操作员调用:
foo6 = foo4.ToUpper();
foo6 = CFoo("Well well well");
每当从相同类型的xvalue初始化对象时,都会调用move构造函数,其中包括:
- 初始化,
T a = std::move(b);
或T a(std::move(b));
,其中b
的类型为T
- 传递函数参数:
f(std::move(a));
,其中a
的类型为T
,f
为void f(T t)
- 函数return:
T f()
等函数内部的return a;
,其中a
的类型为T
,具有move构造函数
有关更多信息,请参阅cppreference.com上的移动构造函数。
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?