标签: lvalue

说明符和限定符之间的相关性?

constvolatile被称为cv-qualifier由C规格.

specifierqualifier(cv-qualifier)之间究竟有什么区别?限定符也是一个说明符吗?

是否必须qualifier只有左值?

什么是限定词以外的cv-qualifier

我的上述理解是否有意义?

c++ lvalue

12
推荐指数
2
解决办法
1266
查看次数

C++ 0x:rvalue引用与非const lvalue

在C++ 03中编程时,我们无法将未命名的临时文件T()传递给函数void foo(T&);.通常的解决方案是给临时名称,然后传递它:

T v;
foo(v);
Run Code Online (Sandbox Code Playgroud)

现在,沿着C++ 0x - 现在使用rvalue引用,定义为的函数void foo(T&&)将允许我传递临时值.这让我想到了一个问题:因为一个采用右值引用的函数可以同时使用右值引用(未命名的临时值)以及左值引用(命名为非const引用),是否有理由在函数参数中再使用左值引用?我们不应该总是使用rvalues作为函数参数吗?

当然,一个采用左值引用的函数会阻止调用者传递临时值,但我不确定这是否是一个有用的限制.

c++ lvalue rvalue-reference c++11

12
推荐指数
1
解决办法
2308
查看次数

Const引用和左值

我们不能写,int& ref = 40因为我们需要lvalue在右侧.但我们可以写const int& ref = 40.为什么这可能?rvalue而是40lvalue

我知道这是一个例外,但为什么呢?

c++ rvalue lvalue

12
推荐指数
2
解决办法
4156
查看次数

为什么这里的枚举变量是右值?

例子:

typedef enum Color
{
    RED,
    GREEN,
    BLUE
} Color;

void func(unsigned int& num)
{
    num++;
}

int main()
{
    Color clr = RED;
    func(clr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时出现以下错误:

<source>: In function 'int main()':

<source>:16:9: error: cannot bind non-const lvalue reference of type 'unsigned int&' to an rvalue of type 'unsigned int'

     func(clr);

         ^~~
Run Code Online (Sandbox Code Playgroud)

我认为clr我传递给的变量 ( )func(unsigned int&)是一个左值。我可以获得的地址clr并可以为其分配另一个值。当我尝试将它传递给 时,为什么它会变成右值func(unsigned int&)

c++ rvalue lvalue rvalue-reference c++11

12
推荐指数
1
解决办法
931
查看次数

为什么数组类型对象不可修改?

据说这里

术语可修改的左值用于强调左值允许指定的对象被改变以及被检查.以下对象类型是左值,但不是可修改的左值:

  • 数组类型
  • 不完整的类型
  • const限定类型
  • 结构或联合类型,其成员之一被限定为const类型

因为这些左值不可修改,所以它们不能出现在赋值语句的左侧.

为什么数组类型对象不可修改?写不正确

int i = 5, a[10] = {0};    
a[i] = 1;
Run Code Online (Sandbox Code Playgroud)


而且,什么是不完整的类型?

c arrays lvalue

11
推荐指数
2
解决办法
4158
查看次数

可以推断出左值引用非类型模板参数吗?

我有以下代码,我无法工作:

struct foo {};
foo foo1 = {};

template <foo& F>
class FooClass {};

template <foo& F>
void foobar(FooClass<F> arg) {
}

int main() {
    FooClass<foo1> f;
    foobar(f);
}
Run Code Online (Sandbox Code Playgroud)

错误是:

main.cpp:14:5:错误:没有匹配函数来调用'foobar'

注意:候选模板被忽略:替换失败:推导出的非类型模板参数与其对应的模板参数('foo'vs'foo&')的类型不同

是否可以推断左值参考模板参数?如果是这样,应该怎么做?

c++ templates lvalue language-lawyer c++11

11
推荐指数
1
解决办法
292
查看次数

在C语言中,在语义上是否可以创建一个不完整类型的左值?

在C89标准中,我发现了以下部分:

3.2.2.1左值和函数指示符

除非它是sizeof运算符的操作数,一元&运算符,++运算符, - 运算符或者左运算符.运算符或赋值运算符,没有数组类型的左值将转换为存储在指定对象中的值(并且不再是左值).如果左值具有限定类型,则该值具有左值类型的非限定版本; 否则该值具有左值的类型.如果左值具有不完整类型且没有数组类型,则行为未定义.

如果我正确读取它,它允许我们创建一个lvalue并在其上应用一些运算符,这些运算符在运行时编译并可能导致未定义的行为.

问题是,我想不出一个"不完整类型的左值"的例子,它可以传递编译器的语义检查和触发器undefined behavior.

考虑一个左值是

左值是表达式(与对象类型或大于空隙以外的不完全类型)指定的一个对象.

那个不完整的类型是

类型被划分为对象类型(描述对象的类型),函数类型(描述函数的类型)和不完整类型(描述对象但缺少确定其大小所需的信息的类型).

我试过一个失败的程序:

struct i_am_incomplete;
int main(void)
{
    struct i_am_incomplete *p;
    *(p + 1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并得到以下错误:

error: arithmetic on a pointer to an incomplete type 'struct i_am_incomplete'
    *(p + 1);
      ~ ^
Run Code Online (Sandbox Code Playgroud)

任何人都可以想到这方面的例子吗?"不完整类型的左值"的示例,它可以传递编译器的语义检查和触发器undefined behavior.


更新:

正如@algrid在答案中所说,我误解了undefined behavior,其中包含compile error了一个选项.

也许我是鸡蛋里挑骨头,我还在这里想知道的根本动机喜欢undefined behaviordisallowing an lvalue to have an incomplete type.

c lvalue undefined-behavior language-lawyer incomplete-type

11
推荐指数
2
解决办法
628
查看次数

什么是动态类型的对象

我认为动态类型意味着动态分配对象使用new.在下面的例子中,您是否p指出动态类型或静态类型的对象?在标准中,它没有说动态类型是动态对象.

1.3.3 - 由左值表达式表示的左值所指的最派生对象(1.8)的类型.[示例:如果指针(8.3.1)p的静态类型是"指向B类的指针"指向D类的对象,从B派生(第10节),则表达式*p的动态类型为"D" ".参考文献(8.3.2)的处理方式相似.]

以下引用的含义是什么呢?

rvalue表达式的动态类型是其静态类型

class Base {
    virtual void foo(){}
};

class Derived : public Base {
    void foo(){}
};

int main()
{
    Derived d;
    Base *p = &d;
}
Run Code Online (Sandbox Code Playgroud)

c++ inheritance pointers lvalue subobject

10
推荐指数
3
解决办法
5258
查看次数

为什么C中的复合文字可以修改

人们通常将"不可修改的"与术语"文字"联系起来

char* str = "Hello World!";
*str = 'B';  // Bus Error!
Run Code Online (Sandbox Code Playgroud)

然而,当使用复合文字时,我很快发现它们是完全可修改的(并且锁定在生成的机器代码上,你会看到它们被推到堆栈上):

char* str = (char[]){"Hello World"};
*str = 'B';  // A-Okay!
Run Code Online (Sandbox Code Playgroud)

我正在编译clang-703.0.29.这两个例子不应该生成完全相同的机器代码吗?如果它是可修改的,复合文字真的是文字吗?

编辑:一个更短的例子是:

"Hello World"[0] = 'B';  // Bus Error!
(char[]){"Hello World"}[0] = 'B';  // Okay!
Run Code Online (Sandbox Code Playgroud)

c c99 literals compound-literals lvalue

10
推荐指数
1
解决办法
1226
查看次数

为什么我的代码打印两次右值而不是右值和左值?

因此,我想练习的用法,std::forward并创建了Test具有2个构造函数的类。1个带T&,另一个带T&&作为过载。T&打印左值,并T&&打印右值,所以我知道正在使用哪个构造函数。我在堆栈上创建了2个类的实例,令我惊讶的是,这两个实例都使用了T&&重载。

#include <iostream>
#include <type_traits>
#include <utility>

template <class T> auto forward(T &&t) {
  if constexpr (std::is_lvalue_reference<T>::value) {
    return t;
  }
  return std::move(t);
}

template <class T> class Test {
public:
  Test(T &) { std::cout << "lvalue" << std::endl; };
  Test(T &&) { std::cout << "rvalue" << std::endl; };
};

int main() {
  int x = 5;
  Test<int> a(forward(3));
  Test<int> b(forward(x));
  return …
Run Code Online (Sandbox Code Playgroud)

c++ forward rvalue lvalue stdmove

10
推荐指数
1
解决办法
194
查看次数