我刚刚对那些(相当)新功能进行了一些研究,我想知道为什么C++委员会决定为它们引入相同的语法?似乎开发人员不必浪费一些时间来理解它是如何工作的,并且一个解决方案让我们考虑进一步的问题.在我的情况下,它从问题开始,可以简化为:
#include <iostream>
template <typename T>
void f(T& a)
{
std::cout << "f(T& a) for lvalues\n";
}
template <typename T>
void f(T&& a)
{
std::cout << "f(T&& a) for rvalues\n";
}
int main()
{
int a;
f(a);
f(int());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我首先在VS2013上编译它,它按照我的预期工作,结果如下:
f(T& a) for lvalues
f(T&& a) for rvalues
Run Code Online (Sandbox Code Playgroud)
但有一个可疑的事情:intellisense强调了f(a).我做了一些研究,我明白这是因为类型崩溃(Scott Meyers将它命名为通用引用),所以我想知道g ++对它的看法.当然它没有编译.微软实现他们的编译器以更直观的方式工作是非常好的,但我不确定它是否符合标准,是否应该在IDE中存在这种差异(编译器与智能感知,但实际上可能存在在某种程度上是有道理的).好的,回到问题所在.我用这种方式解决了它:
template <typename T>
void f(T& a)
{
std::cout << "f(T& a) for lvalues\n";
}
template <typename T>
void f(const T&& a)
{
std::cout << "f(T&& a) for …Run Code Online (Sandbox Code Playgroud) 我发布了这个答案:https://stackoverflow.com/a/28459180/2642059其中包含以下代码:
void foo(string&& bar){
string* temp = &bar;
cout << *temp << " @:" << temp << endl;
}
Run Code Online (Sandbox Code Playgroud)
是bar左值还是左值?
我问,因为我显然不能取rvalue的地址,但我可以在这里完成rvalue引用的地址.
如果你可以对左值参考执行任何操作,你可以在左值参考上区分用"&&"而不仅仅是"&"来区分两者?
假设我有一个函数的两个重载f.f(T&&)和f(T&).然后在身体g:
g(T&& t) { f(t);}过载f(T&)将调用因为t被认为是左值.
这对我来说非常令人惊讶.带签名的函数如何f(T&&)与类型的调用不匹配T&&?让我更加惊讶的是,一个电话f(static_cast<T&&>(t))实际上会调用rvalue超载f(T&&).
使这成为可能的C++规则是什么?是T&&不是类型吗?
我有一个类似 5 年前发布的类似性质的问题: 为什么右值引用变量不是右值?
我主要关心的是为什么我可以这样做:
int&& k = 3;
k++;
Run Code Online (Sandbox Code Playgroud)
但我不能这样做:
(static_cast<int&&>(3))++;
Run Code Online (Sandbox Code Playgroud)
我总是将右值引用解释为左值,因为右值引用变量是左值。但显然情况并非如此。有人可以向我解释为什么(static_cast<int&&>(3))++;结果是using rvalue as lvalue?
我知道命名引用是左值:
int x = 1;
int& ref1 = x;
int&& ref2 = std::move(x);
Run Code Online (Sandbox Code Playgroud)
我读过解释——那是因为我们可以获取那些ref1和的地址ref2。
但是当我们获取引用的地址时,我们实际上获取了被引用对象的地址,不是吗?所以这个解释似乎不太正确。
那么为什么命名引用是左值呢?
我想当一个通用引用参数与一个右值引用参数匹配时,会返回一个右值引用参数.但是,我的测试显示rvalue引用被通用引用函数模板转换为左值引用.为什么会这样?
#include <iostream>
#include <type_traits>
using namespace std;
template <typename T>
T f1(T&&t) { //<-----this is a universal reference
cout << "is_lvalue reference:" << is_lvalue_reference<T>::value << endl;
cout << "is_rvalue reference:" << is_rvalue_reference<T>::value << endl;
cout << "is_reference:" << is_reference<T>::value << endl;
return t;
}
void f2(int&& t) {
cout << "f2 is_lvalue reference:" << is_lvalue_reference<decltype(t)>::value << endl;
cout << "f2 is_rvalue reference:" << is_rvalue_reference<decltype(t)>::value << endl;
cout << "f2 is_reference:" << is_reference<decltype(t)>::value << endl;
f1(t);
}
int main()
{ …Run Code Online (Sandbox Code Playgroud) c++ rvalue-reference lvalue-to-rvalue perfect-forwarding c++11
我将右值传递给std::move(x),testForward(T&& v)但它print(T& t)在内部调用。
看起来右值v在调用之前已经变成了左值print()。我不知道为什么会发生这种情况。谁能解释一下吗?
#include<iostream>
using namespace std;
template<typename T>
void print(T& t) {
std::cout << "Lvalue ref" << std::endl;
}
template<typename T>
void print(T&& t) {
std::cout << "Rvalue ref" << std::endl;
}
template<typename T>
void testForward(T&& v) {
print(v); // call print(T& t);
}
int main(int argc, char* argv[])
{
int x = 1;
testForward(std::move(x)); // output: Lvalue ref
}
Run Code Online (Sandbox Code Playgroud)