相关疑难解决方法(0)

初始化是否需要左值到右值的转换?是`int x = x;`UB?

C++标准包含一个半着名的例子,在3.3.2中的"令人惊讶的"名称查找,"声明点":

int x = x;
Run Code Online (Sandbox Code Playgroud)

这初始化x自身,(原始类型)未初始化,因此具有不确定的值(假设它是一个自动变量).

这实际上是未定义的行为吗?

根据4.1"左值到右值转换",对未初始化的值执行左值到右值的转换是未定义的行为.右手是否x接受这种转换?如果是这样,示例实际上会有未定义的行为吗?

c++ initialization undefined-behavior language-lawyer

55
推荐指数
2
解决办法
2411
查看次数

为什么字符串文字是l值,而所有其他文字都是r值?

C++ 03 5.1主要表达式
§2:

文字是主要表达方式.它的类型取决于它的形式(2.13).字符串文字是左值; 所有其他文字都是右值.

这背后的理由是什么?
据我所知,字符串文字是对象,而所有其他文字都不是.并且l值总是指对象.

但问题是为什么字符串文字是对象,而所有其他文字都不是?
这个理由在我看来更像是鸡蛋或鸡肉问题.

我理解这个问题的答案可能与硬件架构有关,而不是C/C++作为编程语言,但我想听到同样的看法.

注意:我将此问题标记为c&c ++,因为C99标准也有类似的引用,特别是§6.5.1.4

c c++ literals string-literals

53
推荐指数
4
解决办法
5760
查看次数

xvalues,glvalues和prvalues的真实例子?

我想知道是否有人可以告诉或解释一些xvalues,glvalues和prvalues的真实例子?我读过类似的问题:

什么是右值,左值,x值,glvalues和prvalues?

但我不明白每个人的意思.任何人都可以解释在什么情况下这些值是重要的,何时应该使用它们?

c++ c++11

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

为什么不能取nullptr的地址?

在C++ 11标准,为什么服用nullptr是不允许的,而一个地址,我不明白其中的道理允许携带自己的std :: nullptr_t实例的地址.除了nullptr是保留关键字这一事实之外,是否有任何指定的推理作出此决定?

仅仅因为它让我很开心,我试图用以下函数环绕这个限制:

decltype(nullptr)* func(const decltype(nullptr) &nref) noexcept
{
    return const_cast<decltype(nullptr)*>(reinterpret_cast<const decltype(nullptr)*>(&nref));
}
Run Code Online (Sandbox Code Playgroud)

我不得不在参数上使用reinterpret_cast,因为没有它我得到了歇斯底里的错误:

error: invalid conversion from 'std::nullptr_t*' to 'std::nullptr_t*' [-fpermissive]
Run Code Online (Sandbox Code Playgroud)

当我通过直接传递nullptr来调用此函数时,每次都会得到一个不同的地址.是否为nullptr动态分配地址及时进行比较等?或者(可能更有可能)编译器可能强制执行底层对象的临时副本?

当然,这些都不是至关重要的信息,我只是觉得有趣的是为什么要实施这一特定的限制(以及随后为什么我会看到我的行为).

c++ std nullptr c++11

41
推荐指数
3
解决办法
3840
查看次数

左值隐式转换的左值

我看到整个C++标准中许多地方使用的术语"左值到右值转换".据我所知,这种转换通常是隐含的.

标准中的一个意外(对我来说)特征是他们决定将左值作为转换处理.如果他们说glvalue总是可以接受而不是prvalue怎么办?这句话实际上会有不同的含义吗?例如,我们读到lvalues和xvalues是glvalues的例子.我们没有读到lvalues和xvalues可以转换为glvalues.意义上有区别吗?

在我第一次遇到这个术语之前,我曾经或多或少地对lvalues和rvalues进行了如下建模:"lvalues 总是能够充当rvalues,但另外还可以出现在左侧=和右侧&".

对我来说,这是一个直观的行为,如果我有一个变量名,那么我可以将该名称放在我想放置文字的地方.此模型似乎与标准中使用的左值到右值隐式转换术语一致,只要保证发生此隐式转换即可.

但是,因为他们使用这个术语,我开始想知道在某些情况下是否可能无法进行隐式左值到右值转换.也就是说,也许我的心理模型在这里是错误的.以下是该标准的相关部分:(感谢评论者).

每当glvalue出现在期望prvalue的上下文中时,glvalue就会转换为prvalue; 见4.1,4.2和4.3.[注意:尝试将rvalue引用绑定到左值不是这样的上下文; 见8.5.3 .-结束说明]

我理解他们在说明中描述的内容如下:

int x = 1;
int && y = x; //in this declaration context, x won't bind to y.
// but the literal 1 would have bound, so this is one context where the implicit 
// lvalue to rvalue conversion did not happen.  
// The expression on right is an lvalue. if it had been a prvalue, it would have bound.
// Therefore, the lvalue …
Run Code Online (Sandbox Code Playgroud)

c++ implicit-conversion lvalue-to-rvalue c++11

41
推荐指数
2
解决办法
1万
查看次数

NULL宏实际上可以是nullptr吗?

根据标准N4713(7.11/1)的草案:

空指针常量是一个整数文字(5.13.2),其值为零或prvalue类型std::nullptr_t.

和21.2.3/2:

NULL是一个实现定义的空指针常量.

以下NULL可以定义为nullptr.cppreference上提到了相同的内容:

#define NULL 0
//since C++11
#define NULL nullptr
Run Code Online (Sandbox Code Playgroud)

同时"Additive operators"条款说(8.5.6/7):

如果将值0添加到空指针值或从空指针值中减去该值,则结果为空指针值.如果减去两个空指针值,则结果将等于0转换为该类型的值std::ptrdiff_t.

因此,以下代码应该是有效的:

0 + nullptr; 
nullptr - nullptr; 
Run Code Online (Sandbox Code Playgroud)

但由于缺乏+/-运营商对于std::nullptr_t代码是无效的.

有没有我没有考虑到的东西或NULL宏不能实际定义为nullptr

c++ null nullptr language-lawyer

41
推荐指数
4
解决办法
3207
查看次数

右值引用是否允许悬空引用?

考虑以下.

#include <string>
using std::string;

string middle_name () {
    return "Jaan";
}

int main ()
{
    string&& danger = middle_name();   // ?!
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不会计算任何东西,但它编译时没有错误,并演示了一些让我感到困惑的事情:danger是一个悬空引用,不是吗?

c++ rvalue c++11

31
推荐指数
2
解决办法
3064
查看次数

什么表达式创建xvalues?

我正在尝试理解C++ 11的概念.

我所说的标准草案:

xvalue("eXpiring"值)也指对象,通常接近其生命周期的末尾(例如,可以移动其资源).xvalue是涉及rvalue引用的某些表达式的结果(8.3.2).[示例:调用返回类型为右值引用的函数的结果是xvalue. - 末端的例子]

那么,产生xvalues的"某种表达式" 到底什么?规范的这一部分没有详细说明这些表达式的列表.

我理解左值和右值(至少我认为,我理解).

c++ language-lawyer xvalue c++11

25
推荐指数
2
解决办法
4091
查看次数

根据经验确定C++ 11表达式的值类别?

C++ 11中的每个表达式都有一个值类别.lvalue,xvalue或prvalue之一.

有没有办法编写一个宏,给定任何表达式作为参数,将产生一个字符串"lvalue","xvalue"或"prvalue"酌情?

例如:

int main()
{
    int x;

    cout << VALUE_CAT(x) << endl; // prints lvalue
    cout << VALUE_CAT(move(x)) << endl; // prints xvalue
    cout << VALUE_CAT(42) << endl; // prints prvalue
}
Run Code Online (Sandbox Code Playgroud)

怎么可以VALUE_CAT实现?

c++ c++11

25
推荐指数
1
解决办法
1007
查看次数

为什么文字和临时变量不是左值?

我读过的lvalues是"具有已定义存储位置的内容".

而且文字和临时变量也不是左值,但没有给出这个陈述的理由.

是因为文字和临时变量没有定义存储位置?如果是的话,那么如果不在记忆中它们会在哪里居住?

我想在"定义的存储位置"中"定义"有一些意义,如果有(或没有)请告诉我.

c++ rvalue lvalue c++11

24
推荐指数
4
解决办法
1940
查看次数