标签: value-categories

为什么std :: move()在c ++中工作?

以下是代码段:

int i=0;
int&&k=std::move(i);
Run Code Online (Sandbox Code Playgroud)

在c ++入门中,此举是

template <typename T>
typename remove_reference<T>::type &&move(T&& t)
{return static_cast<typename remove_reference<T>::type&&>(t);}
Run Code Online (Sandbox Code Playgroud)

据我所知,这个std::move模板会扣除一个像这样的函数

int&& move(int& t){return static_cast<int&&>(t);}
Run Code Online (Sandbox Code Playgroud)

作为比较和阐述我的问题,请考虑这样的示例:

 int test(int k){k=66;return k;}
 int k;
 int a=test(k);
Run Code Online (Sandbox Code Playgroud)

上面的代码将编译为:

int temp;//the temporary object
temp=k;
int a=temp;
Run Code Online (Sandbox Code Playgroud)

同样,我认为第一个代码片段将被编译为:

int&& temp=0;
int&& k=temp;//oop!temp is an lvalue!
Run Code Online (Sandbox Code Playgroud)

这似乎是错误的,因为它temp是一个左值,我有什么不对吗?

c++ c++11 value-categories stdmove

6
推荐指数
1
解决办法
392
查看次数

为什么在某些情况下,cv-qualifiers从函数返回类型中删除?

看这个简单的例子:

template <typename T>
const T const_create() {
    return T();
}

struct Foo { };

int main() {
    auto &x = const_create<Foo>(); // compiles
    // auto &x = const_create<int>(); // doesn't compile
}
Run Code Online (Sandbox Code Playgroud)

为什么版本可以Foo编译,而int不能编译?换句话说,为什么const要从返回类型中删除const_create<int>?它的工作方式就像它返回一样int,不是const int。这不是语言上的矛盾吗?

标准在哪里规定这种行为?

c++ const value-categories

6
推荐指数
1
解决办法
52
查看次数

cppreference是否使用术语“ [对象的身份]”对c ++ 11和c ++ 17有两种不同的含义?

我以为我已经设法完全理解(在其他SO问题的帮助下,谢谢)关于值类别的C ++ 17的更改,但是现在我注意到了这个问题,这表明我不太了解它们。

在C ++ 11中,对值类别有“具有身份/可以从中移出”的解释,并且cppreference中仍然存在“身份”的含义的定义:

具有同一性:可以通过比较对象的地址或它们标识的功能(直接或间接获得)来确定该表达式是否与另一个表达式引用相同的实体。

在C ++ 17中,“具有身份/可以从其移出”不再成立,但是新定义也基于“身份”的概念:

glvalue(“广义” lvalue)是一个表达式,其求值确定对象,位字段或函数的身份;

我的问题/误解是:这是“身份”的相同意思,还是不同的“身份”?据我了解,c ++ 17中的情况如下:

A f() { return A(); }

A a = f(); // 1: f() is a prvalue expression, used to directly initialize a.
f();       // 2: f() is a prvalue expr., converted to xvalue by temporary materialization
A&& r = f(); // 3: f() is a prvalue expr., converted to xvalue by temporary materialization
Run Code Online (Sandbox Code Playgroud)

在第二和第三种情况下,我获得一个xvalue,这意味着它应该具有一个标识。因此,我应该能够得到它的地址 [编辑:]我应该能够确定它是否与某些其他表达式引用相同的实体,但是我认为我不能。当然,在第三种情况下,我可以将“&r”作为单独的命令执行,然后将其地址与另一个表达式的地址进行比较,但这是因为A &&是左值。是通过A &&取得地址,在这种情况下,“直接或间接获得”是什么意思?我认为这不是正确的答案,因为在C ++ 11中,我也可以轻松地做到

A&& r = …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++11 c++17 value-categories

6
推荐指数
1
解决办法
151
查看次数

为什么在提到纯右值时在这里使用术语“对象”?

据我所知,在 c++17 中,纯右值的概念/语义不再是临时对象,因此在许多情况下强制执行复制省略。

然而,今天我遇到了return 表达式的描述

如果表达式是纯右值,则函数返回的对象将直接由该表达式初始化。当类型匹配时,这不涉及复制或移动构造函数

为什么“对象一词出现在这里?在值类别中,不是引用类型的函数的返回属于纯右值,所以我认为使用术语对象可能是不合适的。

根据我的理解,纯右值现在不再是对象,它们只是值,对吗?

作为补充,这里也使用术语“对象”。

c++ language-lawyer semantics c++17 value-categories

5
推荐指数
1
解决办法
265
查看次数

我应该参考lambda吗?

我应该参考lambda以避免复制吗?

这段代码会复制lambda吗:

auto myLambda = []() {/* do stuff */ }
Run Code Online (Sandbox Code Playgroud)

如果是的话,我应该这样写吗:

auto &myLambda = []() {/* do stuff */ }
Run Code Online (Sandbox Code Playgroud)

PS:很抱歉,有人用谷歌搜索了一个可能是新手的问题,但没有找到答案。

c++ lambda reference value-categories

5
推荐指数
1
解决办法
76
查看次数

在右值参考参数上使用std :: move的原因

我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分

void push_back(object &&x) {
        //do something
        objects[size++] = std::move(x);
    }
Run Code Online (Sandbox Code Playgroud)

我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?

另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:

A& operator=(A&& other) {
     member = std::move(other.member);
     return *this;
}
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-semantics c++11 value-categories

5
推荐指数
2
解决办法
106
查看次数

左值引用prvalue的地址代表什么?

当函数参数的类型为lvalue时lref:

void PrintAddress(const std::string& lref) {
  std::cout << &lref << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

并且lref与一个prvalue绑定:

PrintAddress(lref.substr() /* temporary of type std::string */)
Run Code Online (Sandbox Code Playgroud)

地址代表什么?那里住着什么?

prvalue无法获取其地址.但是 prvalue 的左值引用可以得到它的地址,这对我很好奇.

c++ value-categories

4
推荐指数
2
解决办法
274
查看次数

在C++中,st*:: move在T*类型上的意外行为

我有下面的代码段,其中i声明一个称为变量pval,其尝试导出T&&上的T*[与Tint].根据类型信息[使用abi解码],导出的类型是int*.

但是当我比较它的int*类型时,decltype(pval)它返回零而不是1,这意味着它被视为pval不同的类型int*.那么哪一个是由报告的错误pval存在或哪个指示比较为错误.int*typeidis_same

#include<iostream>
#include<string>
#include<typeinfo>
#include<cxxabi.h>
#include<type_traits>

using namespace std;

std::string classname(const std::type_info& info)
{
    int status;
    char* rslt=abi::__cxa_demangle(info.name(),0,0,&status);
    std::string result(rslt);
    free(rslt);
    return result;
}

int main(int argc, char* argv[])
{
    int* ptr = new int(10);
    decltype(std::move(ptr)) pval = std::move(ptr);
    cout << classname(typeid(pval)) << endl;             // as per typeid information the type of pval is …
Run Code Online (Sandbox Code Playgroud)

c++ typeid decltype c++11 value-categories

4
推荐指数
1
解决办法
116
查看次数

条件运算符的值类别

请考虑以下代码:

int x;
int& f() {
  return x ? x : throw 0;
}
Run Code Online (Sandbox Code Playgroud)

随着gcc version 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)我得到以下编译错误:

cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
Run Code Online (Sandbox Code Playgroud)

请注意,这在clang中编译得很好.以下是(我相信的)标准中的相关陈述:

N4659 [8.16.2.1](条件运算符):
第二个或第三个操作数(但不是两个)是一个(可能带括号的)throw-expression(8.17); 结果是另一个的类型和值类别.

据我所知,x是一个左值,所以在我看来clang是对的.我错了吗?


如果我不得不猜测,那么l-to-rvalue转换正在发生,因为条件中的两个表达式没有相同的类型,但因为第二个是抛出,所以应该抢占此转换.我不熟悉提交错误报告,但也许这将是一个更好的论坛.
以下是关于条件运算符的一些(可能)更有用的问题:
为什么此函数在给定rvalue参数的情况下返回左值引用?
错误:这个简单的C代码需要左值?(三元有任务吗?)

c++ g++ conditional-operator language-lawyer value-categories

4
推荐指数
1
解决办法
151
查看次数

生命周期延长、纯右值和 xvalues

遵循这个问题的公认答案Do rvalue references allow dangling references?当分配给右值引用左值时,xvalues 的生命周期似乎没有延长,就像问题中一样。但是,当我这样做时

#include <iostream>

using namespace std;

class Something {
public:
    Something() {
        cout << "Something()" << endl;
    }
    Something(const Something&) {
        cout << "Something(const Something&)" << endl;
    }
    Something(Something&&) {
        cout << "Something(Something&&)" << endl;
    }
    ~Something() {
        cout << "~Something()" << endl;
    }

    int a;
};

Something make_something() {
    return Something{};
}

int main() {
    auto&& something = make_something().a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

调用返回的对象的生命周期make_something被延长,即使make_something().a是根据http://en.cppreference.com/w/cpp/language/value_category的 xvalue (xvalues …

c++ xvalue c++11 prvalue value-categories

3
推荐指数
1
解决办法
649
查看次数