【发布时间】:2018-02-19 11:57:26
【问题描述】:
因此,为了便于理解,我只是编写了std::forward 的示例和人为示例,但它并没有按我预期的方式工作。在下面的程序中
#include <string>
#include <iostream>
struct A
{
A(const std::string& m) : m_(m) {};
std::string m_;
};
template<typename T>
void funcB(T&& obj) // universal reference
{
std::string local = std::move(obj.m_); // using std::move on universal reference. Bad.
std::cout << "funcB : " << local << '\n';
}
template<typename T>
void funcC(T&& obj) // universal reference
{
std::string local = std::forward<std::string>(obj.m_); // using std::move on universal reference
std::cout << "funcC : " << local << '\n';
}
template<typename T>
void funcD(T&& obj) // universal reference
{
T local = std::forward<T>(obj); // using std::move on universal reference
std::cout << "funcD : " << local.m_ << '\n';
}
int main()
{
A obj("firstString");
//funcA(obj); // We get compiler error. Rvalue reference cannot be bound to Lvalue
funcB(obj);
std::cout << "Main : " << obj.m_ << '\n';
A obj2("secondString");
funcC(obj2);
std::cout << "Main : " << obj2.m_ << '\n';
A obj3("thirdString");
funcD(obj3);
std::cout << "Main : " << obj3.m_ << '\n';
}
在输出中
funcB : firstString
Main :
funcC : secondString
Main :
funcD : thirdString
Main : thirdString
在funcC 中,即使我使用了通用引用并且在这里它绑定到左值,但当我执行std::forward<std::string> 时,字符串会被移动。因此在最后一行,在“Main:”之后没有输出。即使 obj 绑定到 Lvalue,有人可以请教如何移动字符串。
重读一本书后才意识到这个问题的答案。
在funcC中,std::forward<std::string>(obj.m_)相当于移动字符串。
但是在funcD中,std::forward被实例化为std::forward<struct A&>(obj),被复制了。
【问题讨论】:
-
顺便说一下,现在叫转发参考,而不是通用参考。
-
既然是C++17吗?
-
@avi007: Basically, yes,尽管除了标准之外,这已经是几年来的常用术语了。唯一实际的标准更改是添加这个名称(旧名称从未在其中),因此在讨论符合 C++ 以来任何标准的代码时,您可能可以安全地应用新流行的术语11.