调用函数时没有调用构造函数
No constructor called when calling function
MyType
定义了复制和移动构造函数。执行以下代码片段时(使用 VS2015 编译后):
template<typename T>
void f(T&& o) {
// do something with o
}
int main() {
MyType o{ 1, 2, 3 };
f(o); // call of copy-constructor expected
f(std::move(o)); // call of move-constructor expected
}
我本来希望在第一次调用 f
之后调用复制构造函数,在第二次调用 f
之后调用移动构造函数。但是在任何情况下实际上都没有调用构造函数。我怀疑此行为是编译器优化,但不确定可移植性或是否符合标准。
这两个调用都是通过引用 - 第一个是 lvalue 引用,第二个是 rvalue 引用。 T&&
与两者一起使用,称为 forward reference (N4164). Scott Meyers called them universal references 并且作为模板参数和 auto&&
.
特别有用
std::move
用于表示所有权转移但实际上不做任何动作。它的效果是 static_cast 到右值引用。
所以你有:
void f(MyType& ) {}
void f(MyType&& ) {}
...
f(o); // calls void f(MyType& )
f(static_cast<MyType&&>(o)); // calls void f(MyType&& )
移动构造函数通常在对象初始化时调用。
Move constructors cppreference.com
The move constructor is called whenever selected by overload
resolution, which typically occurs when an object is initialized (by
direct-initialization or copy-initialization) from rvalue (xvalue or
prvalue) (until C++17)xvalue (since C++17) of the same type, including
initialization: T a = std::move(b);
or T a(std::move(b));
, where b is of type T;
function argument passing: f(std::move(a));
, where a is of type T and f is void f(T t);
function return: return a;
inside a function such as T f()
, where a is of type T which has a move constructor.
如果将 f
更改为 void f(T o)
,将在第一次调用时调用复制构造函数,在第二次调用时调用移动构造函数。
MyType
定义了复制和移动构造函数。执行以下代码片段时(使用 VS2015 编译后):
template<typename T>
void f(T&& o) {
// do something with o
}
int main() {
MyType o{ 1, 2, 3 };
f(o); // call of copy-constructor expected
f(std::move(o)); // call of move-constructor expected
}
我本来希望在第一次调用 f
之后调用复制构造函数,在第二次调用 f
之后调用移动构造函数。但是在任何情况下实际上都没有调用构造函数。我怀疑此行为是编译器优化,但不确定可移植性或是否符合标准。
这两个调用都是通过引用 - 第一个是 lvalue 引用,第二个是 rvalue 引用。 T&&
与两者一起使用,称为 forward reference (N4164). Scott Meyers called them universal references 并且作为模板参数和 auto&&
.
std::move
用于表示所有权转移但实际上不做任何动作。它的效果是 static_cast 到右值引用。
所以你有:
void f(MyType& ) {}
void f(MyType&& ) {}
...
f(o); // calls void f(MyType& )
f(static_cast<MyType&&>(o)); // calls void f(MyType&& )
移动构造函数通常在对象初始化时调用。
Move constructors cppreference.com
The move constructor is called whenever selected by overload resolution, which typically occurs when an object is initialized (by direct-initialization or copy-initialization) from rvalue (xvalue or prvalue) (until C++17)xvalue (since C++17) of the same type, including
initialization:
T a = std::move(b);
orT a(std::move(b));
, where b is of type T;function argument passing:
f(std::move(a));
, where a is of type T and f isvoid f(T t);
function return:
return a;
inside a function such asT f()
, where a is of type T which has a move constructor.
如果将 f
更改为 void f(T o)
,将在第一次调用时调用复制构造函数,在第二次调用时调用移动构造函数。