我一直在研究C++ 11的一些新功能,我注意到的是在声明变量时使用的双符号,例如T&& var.
首先,这只野兽叫什么?我希望谷歌允许我们搜索这样的标点符号.
究竟是什么意思?
乍一看,它似乎是一个双重参考(如C风格的双指针T** var),但我很难想到一个用例.
在完美转发中,std::forward用于转换命名的右值引用t1和t2未命名的右值引用.这样做的目的是什么?inner如果我们离开t1&t2作为左值,那将如何影响被调用的函数?
template <typename T1, typename T2>
void outer(T1&& t1, T2&& t2)
{
inner(std::forward<T1>(t1), std::forward<T2>(t2));
}
Run Code Online (Sandbox Code Playgroud) 为什么std::make_unique标准C++ 11库中没有函数模板?我发现
std::unique_ptr<SomeUserDefinedType> p(new SomeUserDefinedType(1, 2, 3));
Run Code Online (Sandbox Code Playgroud)
有点冗长.以下不是更好吗?
auto p = std::make_unique<SomeUserDefinedType>(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
这隐藏得new很好,只提到一次类型.
无论如何,这是我尝试实现make_unique:
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)
我花了很std::forward长时间来编译这些东西,但我不确定它是否正确.是吗?究竟是什么std::forward<Args>(args)...意思?编译器对此做了什么?
我在这里看到了这一点: Move Constructor调用基类Move Constructor
有人能解释一下:
std::move和std::forward,优选用一些代码示例?我只是编写一个通用对象工厂并使用boost预处理器元库来创建一个可变参数模板(使用2010并且它不支持它们).我的函数使用rval引用并std::forward进行完美的转发,它让我思考...当C++ 0X出来并且我有一个标准编译器时,我会使用真正的可变参数模板.但是,我怎么称呼std::forward这些论点?
template <typename ...Params>
void f(Params... params) // how do I say these are rvalue reference?
{
y(std::forward(...params)); //? - I doubt this would work.
}
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一方法就是需要手动拆包... params,我也不是那里.是否有更快的语法可行?
c++ rvalue-reference variadic-templates perfect-forwarding c++11
我一直在观看Scott Meyers 关于 C++和2012 年之后的Universal References的演讲,到目前为止一切都很有意义.然而,一位观众在大约50分钟后问了一个问题,我也在想.迈尔斯说,他不关心答案,因为它不是惯用的,会愚蠢的想法,但我仍然感兴趣.
提供的代码如下:
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
Run Code Online (Sandbox Code Playgroud)
关键是当我们采用右值引用时,我们知道我们有一个右值,所以我们应该std::move保留它是一个右值的事实.当我们采用通用引用(T&&其中T是推导类型)时,我们希望std::forward保留它可能是左值或右值的事实.
所以问题是:既然 …
c++ rvalue-reference move-semantics perfect-forwarding c++11
考虑一个X具有N成员变量的类,每个类都有一些可复制和可移动的类型,以及N相应的setter函数.在C++ 98中,定义X可能如下所示:
class X
{
public:
void set_a(A const& a) { _a = a; }
void set_b(B const& b) { _b = b; }
...
private:
A _a;
B _b;
...
};
Run Code Online (Sandbox Code Playgroud)
X上面类的setter函数可以绑定到左值和右值参数.根据实际的说法,这可能导致创建临时的,并会最终导致的分配副本; 因此,此设计不支持不可复制的类型.
使用C++ 11,我们可以移动语义,完美转发和通用引用(Scott Meyers的术语),通过以下方式重写它们,可以更有效和广泛地使用setter函数:
class X
{
public:
template<typename T>
void set_a(T&& a) { _a = std::forward<T>(a); }
template<typename T>
void set_b(T&& b) { _b = std::forward<T>(b); } …Run Code Online (Sandbox Code Playgroud) c++ move-semantics perfect-forwarding c++11 universal-reference
可能重复:
使用forward的优点
有人可以向我解释一下完美的转发是什么意思吗?
template<typename T> void doSomething(T&& mStuff)
{
auto lambda([&mStuff]{ doStuff(std::forward<T>(mStuff)); });
lambda();
}
Run Code Online (Sandbox Code Playgroud)
mStuff使用&mStuff语法捕获完美转发的变量是否正确?
或者是否有针对完美转发变量的特定捕获语法?
编辑:如果完美转发的变量是参数包怎么办?
此函数的参数将绑定到右值引用:
void f(int && i);
Run Code Online (Sandbox Code Playgroud)
但是,此函数的参数将绑定到右值或左值引用:
template <typename T>
void f(T && t);
Run Code Online (Sandbox Code Playgroud)
我经常听到这被称为通用参考.
我也听说它被称为转发参考.
他们的意思是一样的吗?
如果函数体调用,它只是转发引用std::forward吗?
c++ templates perfect-forwarding universal-reference forwarding-reference