我试图给出一个导致rvalue的操作的简单示例.
这个测试用例应该有效,但令人惊讶的是(对我而言),添加两个ints 的结果不是rvalue(引用).我在这里错过了什么?
void test(int i, int j)
{
// this assert should pass, but fails:
static_assert(std::is_same<decltype(i + j), int&&>(), "i + j should be a rvalue");
// this assert passed, but should fail:
static_assert(std::is_same<decltype(i + j), int>(), "this assert should fail...");
}
Run Code Online (Sandbox Code Playgroud) 我想问为什么as_const禁止rvalue参数,根据 cppreference.com(即为什么标准人员这样做,而不是为什么cppreference.com特别引用它们.而且也不是规范中委员会的意图编纂的地方,只是为了确保:))).这个(人为的)示例会产生错误(用户希望使其为const以保持COW安静)
QChar c = as_const(getQString())[0];
Run Code Online (Sandbox Code Playgroud)
另一个问题的答案指出,如果我们只删除rvalue引用重载的删除,它会默认将rvalues转换为lvalues.是的,但为什么不优雅地处理rvalues并返回rvalue输入的const rvalues和lvalue输入的const lvalues?
强制复制省略是否适用于通过结构化绑定进行分解?以下哪种情况适用于?
// one
auto [one, two] = std::array<SomeClass>{SomeClass{1}, SomeClass{2}};
// two
auto [one, two] = std::make_tuple(SomeClass{1}, SomeClass{2});
// three
struct Something { SomeClass one, two; };
auto [one, two] = Something{};
Run Code Online (Sandbox Code Playgroud)
我怀疑只有第三种情况允许复制省略,因为前两个会被"分解"通过std::get<>并std::tuple_size<>和std::get<>当参数是右值返回xvalues
标准的引用也很好!
我读到这this是一个右值,我们无法通过应用来获取其地址&this。
在我的代码中,我尝试使用的引用绑定this。我想知道哪种地址可以给this?还是都错了?
到底是this什么?左值,右值,关键字还是其他?
void MyString::test_this() const{
std::cout << "this: " << this << std::endl;
const MyString * const& this_ref = this;
std::cout << "thie_ref: " << &this_ref << std::endl;
const MyString * const&& this_right = this;
std::cout << "thie_right: " << &this_right << std::endl;
}
//this: 00CFFC14
//thie_ref: 00CFFB14
//thie_right: 00CFFAFC
Run Code Online (Sandbox Code Playgroud) 有一堆,因为Perl是一种非常含糖的语言,但任何语言中最常用的语句是if语句和设置值的组合.我想我发现了很多,但仍有一些差距.最终,目标是不必多次编写变量名称:
这是我到目前为止所拥有的:
$r ||= $s; # $r = $s unless ($r);
$r //= $s; # $r = $s unless (defined $r);
$r &&= $s; # $r = $s if ($r);
$r = $c ? $s : $t; # if ($c) { $r = $s } else { $r = $t }
$c ? $r : $s = $t; # if ($c) { $r = $t } else { $s = $t }
$r = $s || $t; # if ($s) …Run Code Online (Sandbox Code Playgroud) 前提:
C++ 11 Standard将表达式分为三个不相交的值类别:lvalues,xvalues和prvalues(第3.10/1节).此处提供了对哪些值类别的解释.
我正在努力弄清楚不同运营商对其操作数的价值类别的要求是什么.第3.10/1段规定:
[...]每个表达式都属于此分类法中的基本分类之一:lvalue,xvalue或prvalue.表达式的此属性称为其值类别.[注意:第5章中对每个内置运算符的讨论表明了它产生的值的类别以及它所期望的操作数的值类别.例如,内置赋值运算符期望左操作数是左值,右操作数是prvalue并产生左值作为结果.用户定义的运算符是函数,它们期望和产生的值的类别由它们的参数和返回类型决定. - 尾注]
尽管上面的说明声称,第5条并不总是非常清楚运营商的操作数的价值范畴.例如,关于赋值运算符的操作数的值类别(第5.17/1段),这就是所说的:
赋值运算符(=)和复合赋值运算符都是从右到左分组.所有都需要一个可修改的左值作为左操作数,并返回一个左值操作数的左值.如果左操作数是位字段,则所有情况下的结果都是位字段.在所有情况下,在右和左操作数的值计算之后,以及在赋值表达式的值计算之前,对赋值进行排序.对于不确定序列的函数调用,复合赋值的操作是单个评估.[注意:因此,函数调用不应介入左值到右值的转换和与任何单个复合赋值运算符相关的副作用. - 尾注]
合适的操作数怎么样?
整个5.17节中不再出现"rvalue"和"lvalue"字样.虽然第3.10/1段中的注释明确指出内置赋值运算符期望将prvalue作为右操作数,但在第5.17节中没有明确提到.甚至5.17/1的最后一个注释,提到左值到右值的转换,似乎暗示rvalues是以某种方式预期的(否则转换的需要是什么?),但笔记毕竟是非规范性的.
涉及其他运算符的部分,包括乘法运算符和加法运算符,通常对其操作数的值类别保持沉默.我在标准中找不到任何"默认语句",声明如果没有另外指定,内置运算符的操作数是rvalues.因此,问题.
题:
很高兴参考C++ 11标准.
下面的代码导致未定义的行为.请务必阅读所有答案的完整性.
通过operator<<我链接对象时,我想保留对象的左值/右值:
class Avenger {
public:
Avenger& operator<<(int) & {
return *this;
}
Avenger&& operator<<(int) && {
return *this; // compiler error cannot bind lvalue to rvalue
return std::move(*this);
}
};
void doJustice(const Avenger &) {};
void doJustice(Avenger &&) {};
int main() {
Avenger a;
doJustice(a << 24); // parameter should be Avenger&
doJustice(Avenger{} << 24); // parameter should be Avenger&&
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不能简单地返回*this这意味着类型*this的的rvalue对象仍然是一个lvalue reference.我原以为是rvalue reference …
我正在阅读托马斯·贝克尔关于右值参考及其使用的文章.在那里,他定义了他称之为if-it-a-name规则:
声明为右值引用的事物可以是左值或右值.区别标准是:如果它有一个名字,那么它就是一个左值.否则,它是一个右值.
这对我来说听起来很合理.它还清楚地标识了右值参考的右值.
我的问题是:
class A{
public:
virtual ~A() {};
};
class B : public A{ };
int main(){
A&& p = B();
dynamic_cast<B&&>(std::move(p));
}
Run Code Online (Sandbox Code Playgroud)
抛出错误(g ++ 5.2.0):
error: conversion to non-const reference type 'std::remove_reference<A&>::type& {aka class A&}' from rvalue of type 'A' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)
它试图转换std::move(p)为类型A&,但我无法弄清楚为什么.我会一直认为有必要投p转换为右值引用之前作为右值,但如果我删除std::move它编译罚款.从cppreference:
dynamic_cast < new_type > ( expression )与其他强制转换表达式类似,结果如下:
如果new_type是左值引用类型(表达式必须是左值),则为左值
如果new_type是右值引用类型(表达式可能是左值或右值),则为xvalue
甚至是N3337的5.2.7:
dynamic_cast<T>(v)如果T是指针类型,则v应该是指向完成类类型的指针的prvalue,结果是类型T的prvalue.如果T是左值引用类型,则v应该是完整类类型的左值,并且结果是由T 引用的类型的左值.如果T是右值引用类型,则v应该是具有完整类类型的表达式,并且结果是由T引用的类型的x值.
唯一要求我使用完整的类类型,std::move(p)不是吗?
我想迭代一个临时的valarray,但它不起作用.这是我的(非工作)代码:
#include <iostream>
#include <valarray>
int main()
{
using namespace std;
valarray<int> numerators = {99, 26, 25};
valarray<int> denominators = {9, 2, 5};
for (int i : numerators / denominators) { cout << i << ","; }
// lots of errors
return 0;
}
Run Code Online (Sandbox Code Playgroud)
下面是我想要实现的最小工作示例,除了我不想定义像这样的对象temp_array.
#include <iostream>
#include <valarray>
int main()
{
using namespace std;
valarray<int> numerators = {99, 26, 25};
valarray<int> denominators = {9, 2, 5};
valarray<int> && temp_array = numerators / denominators;
for (int i : …Run Code Online (Sandbox Code Playgroud)