为什么第一个返回引用?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
Run Code Online (Sandbox Code Playgroud)
而第二个不?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
Run Code Online (Sandbox Code Playgroud)
实际上,第二个根本没有编译 - "没有左边的赋值".
int main ()
{
int a = 5,b = 2;
printf("%d",a+++++b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码提供以下错误:
错误:需要左值作为递增操作数
但是,如果我把整个空间a++ +和++b,然后正常工作.
int main ()
{
int a = 5,b = 2;
printf("%d",a++ + ++b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一个例子中的错误是什么意思?
考虑以下代码:
struct foo
{
int a;
};
foo q() { foo f; f.a =4; return f;}
int main()
{
foo i;
i.a = 5;
q() = i;
}
Run Code Online (Sandbox Code Playgroud)
没有编译器抱怨它,甚至Clang.为什么q() = ...线路正确?
#include <iostream>
int main() {
bool b = true;
std::cout << std::is_same<decltype(!(!b)), bool>::value << "\n";
auto bb = (!(!b));
std::cout << std::is_same<decltype(bb), bool>::value << "\n";
}
Run Code Online (Sandbox Code Playgroud)
上面的代码使用不同的编译器有不同的结果。这是编译器错误还是我遗漏了什么?
确定表达式是否是C++中的右值或左值的最佳方法是什么?可能这在实践中没有用,但是因为我正在学习rvalues和lvalues,所以我认为is_lvalue如果在输入中传递的表达式是左值而其他函数返回true 会更好.
例:
std::string a("Hello");
is_lvalue(std::string()); // false
is_lvalue(a); // true
Run Code Online (Sandbox Code Playgroud) 很长一段时间以来,我认为三元运算符总是返回一个右值.但令我惊讶的是,事实并非如此.在下面的代码中,我没有看到返回值foo和三元运算符的返回值之间的区别.
#include <iostream>
int g = 20 ;
int foo()
{
return g ;
}
int main()
{
int i= 2,j =10 ;
foo()=10 ; // not Ok
((i < 3) ? i : j) = 7; //Ok
std::cout << i <<","<<j << "," <<g << std::endl ;
}
Run Code Online (Sandbox Code Playgroud) 有没有办法在C++中编写一个接受左值和右值参数的函数,而不是模板?
例如,假设我编写了一个print_stream从a 读取istream并打印读取到屏幕的数据的函数.
我认为print_stream像这样打电话是合理的:
fstream file{"filename"};
print_stream(file);
Run Code Online (Sandbox Code Playgroud)
以及像这样:
print_stream(fstream{"filename"});
Run Code Online (Sandbox Code Playgroud)
但是我如何声明print_stream这两种用途都有效呢?
如果我声明它
void print_stream(istream& is);
Run Code Online (Sandbox Code Playgroud)
然后第二次使用将无法编译,因为rvalue不会绑定到非const左值引用.
如果我声明它
void print_stream(istream&& is);
Run Code Online (Sandbox Code Playgroud)
然后第一次使用将无法编译,因为左值不会绑定到右值引用.
如果我声明它
void print_stream(const istream& is);
Run Code Online (Sandbox Code Playgroud)
那么函数的实现将无法编译,因为你无法读取const istream.
我不能使该函数成为模板并使用"通用引用",因为它的实现需要单独编译.
我可以提供两个重载:
void print_stream(istream& is);
void print_stream(istream&& is);
Run Code Online (Sandbox Code Playgroud)
并且第二次调用第一次,但这似乎是很多不必要的样板,并且我发现每次用这样的语义编写函数时都必须这样做非常不幸.
我能做些什么吗?
为了使这个代码与C++ 11引用限定符按预期工作,我必须引入一个std::move(*this)听起来不对的代码.
#include<iostream>
struct A{
void gun() const&{std::cout << "gun const&" << std::endl;}
void gun() &&{std::cout << "gun&&" << std::endl;}
void fun() const&{gun();}
void fun() &&{std::move(*this).gun();} // <-- is this correct? or is there a better option
};
int main(){
A a; a.fun(); // prints gun const&
A().fun(); // prints gun&&
}
Run Code Online (Sandbox Code Playgroud)
有些事情听起来不对劲.有std::move必要吗?这是推荐使用吗?目前,如果我不使用它,我会遇到gun const&两种情况,这不是预期的结果.
(似乎*this总是隐式和左值引用,这是有道理的,但然后是逃避使用的唯一方法move)
用clang 3.4和测试gcc 4.8.3.
编辑:这是我从@hvd回答中理解的:
1)std::move(*this)在语法和概念上是正确的
2)但是,如果 …
只是想知道文字字符串是左值还是左值.其他文字(如int,float,char等)是左值还是右值?
函数的返回值是左值还是右值?
你怎么说出差异?
[array objectAtIndex:i] 不能用作L值,因此不能用于在索引i处设置对象.
lvalue ×10
c++ ×7
rvalue ×5
c++11 ×3
c ×2
boolean ×1
cocoa ×1
cocoa-touch ×1
function ×1
objective-c ×1
reference ×1
return-value ×1
this ×1
types ×1