小编Bri*_*ian的帖子

如果nullptr_t不是关键字,为什么char16_t和char32_t?

正如为什么nullptr_t不是关键字所讨论的那样,最好避免引入新关键字,因为它们可能会破坏向后兼容性.

为什么然后是char16_tchar32_t关键词,当他们可以这样定义?

namespace std {
    typedef decltype(u'q') char16_t;
    typedef decltype(U'q') char32_t;
}
Run Code Online (Sandbox Code Playgroud)

c++ c++11

39
推荐指数
1
解决办法
1872
查看次数

在C++中,C风格的演员可以调用转换函数然后抛弃constness吗?

GCC和Clang都拒绝接受以下代码中的C风格演员.

http://coliru.stacked-crooked.com/a/c6fb8797d9d96a27

struct S {
    typedef const int* P;
    operator P() { return nullptr; }
};
int main() {
    int* p1 = const_cast<int*>(static_cast<const int*>(S{}));
    int* p2 = (int*)(S{});
}
Run Code Online (Sandbox Code Playgroud)
main.cpp: In function 'int main()':
main.cpp:7:25: error: invalid cast from type 'S' to type 'int*'
     int* p2 = (int*)(S{});
main.cpp:7:15: error: cannot cast from type 'S' to pointer type 'int *'
    int* p2 = (int*)(S{});
              ^~~~~~~~~~~

但是,根据标准,C风格的演员表可以执行a static_cast后跟a 执行的转换const_cast.这段代码是否格式良好?如果没有,为什么不呢?

c++ language-lawyer

27
推荐指数
1
解决办法
530
查看次数

在标准布局对象(例如,带有offsetof)内进行指针算术时,我们需要使用std :: launder吗?

该问题是针对以下问题的后续措施:当它实际上未指向char数组时,是否将其添加到“ char *”指针UB?

CWG 1314中,CWG确认使用指针在标准布局对象中执行指针算术是合法的unsigned char。这似乎意味着与链接的问题类似的某些代码应按预期工作:

struct Foo {
    float x, y, z;
};

Foo f;
unsigned char *p = reinterpret_cast<unsigned char*>(&f) + offsetof(Foo, z); // (*)
*reinterpret_cast<float*>(p) = 42.0f;
Run Code Online (Sandbox Code Playgroud)

(为了更清楚起见,我用替换charunsigned char。)

但是,似乎C ++ 17中的新更改意味着该代码现在是UB,除非std::launder在两个reinterpret_casts 之后都使用。reinterpret_cast两种指针类型之间的a结果等于两个static_casts:第一个为cv void*,第二个为目标指针类型。但是[expr.static.cast] / 13暗示这会生成指向原始对象的指针,而不是指向目标类型的对象的Foo指针,因为类型的对象不能与unsigned char对象的第一个字节进行指针互换,也不是一个unsigned char对象在的第一个字节f.z指针相互转换与f.z本身。

我很难相信委员会打算进行更改以打破这种非常普遍的习惯用法,从而使C ++ 17之前的所有用法都不offsetof确定。

c++ offsetof language-lawyer c++17

26
推荐指数
1
解决办法
454
查看次数

为什么(int&)0格式不正确?

根据[expr.cast]/4,C风格的强制转换按顺序尝试以下强制转换:

  1. const_cast
  2. static_cast
  3. static_cast 其次是 const_cast
  4. reinterpret_cast
  5. reinterpret_cast 其次是 const_cast

以下演员表格很好:

const_cast<int&>(static_cast<const int&>(0))
Run Code Online (Sandbox Code Playgroud)

然而,GCC和Clang都拒绝演员(int&)0.为什么?

c++ casting const-cast static-cast language-lawyer

24
推荐指数
1
解决办法
434
查看次数

在C++标准中,当违反"shall"要求时,指定要发生什么?

例如,着名的单词(§3.2/ 1)

任何翻译单元都不得包含任何变量,函数,类类型,枚举类型或模板的多个定义.

除非另有说明,否则我认为"必须"的要求应被解释为"除非程序形成不良".然而,其他人则声称"应"代表"否则行为未定义".

在每种情况下,我都会遇到标准,其中"必须"要求后面没有"行为未定义"或"无需诊断"之类的内容,其中发生的规则显然是可以诊断的规则.由我所知的所有编译器诊断出来(以上段落就是一个例子).这就是为什么我认为这意味着"否则程序形成不良",需要诊断.

无论如何,那些只是我的想法.我很欣赏一个权威的答案.

c++ language-lawyer

20
推荐指数
2
解决办法
893
查看次数

哪个草案最接近C++ 14标准?

我在不同的地方看过N3690,N4140和N4296.我猜它是N4140,因为它是在2014年底发布的.N4296似乎有不像C++ 14那样的东西,就像折叠表达式一样.

c++ c++14

20
推荐指数
1
解决办法
1751
查看次数

是POD类型完全等同于琐碎的标准布局类型吗?

在C ++ 20中,不赞成使用POD的概念,因为它是琐碎且标准的布局的无意义的合成特征。但是,C ++ 20草案中的POD定义并不完全是“琐碎的和标准布局”;实际上是:

POD类是既是普通类又是标准布局类的类,并且不具有非POD类类型的非静态数据成员(或其数组)。POD类型是标量类型,POD类,这种类型的数组或这些类型之一的cv限定版本。

换句话说,POD类型不仅是琐碎的而且是标准布局的,而且也是递归的。

该递归需求是否多余?换句话说,如果一个类型既是琐碎的又是标准布局,那么它是否也自动递归地变得琐碎又是标准布局?如果答案为“否”,那么标准布局,琐碎类型却不能成为POD的例子是什么?

c++ language-lawyer standard-layout c++20

20
推荐指数
2
解决办法
229
查看次数

C++ 11:如何获取指针或迭代器指向的类型?

更具体地讲,假设我写template<class Pointer> class Foo,我要声明一个typedef类里面的那个类型*p,如果必须p是类型Pointer.

在C++ 03中,据我所知,唯一的方法是使用类似的东西

typename std::iterator_traits<Pointer>::reference
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是,如果Pointer是一些自定义迭代器类型并且作者忘记扩展std::iterator或以其他方式定义特化,它将不起作用std::iterator_traits.

在C++ 11中,我的同事建议

decltype(*Pointer())
Run Code Online (Sandbox Code Playgroud)

但是如果Pointer不是默认构造的话,这将不起作用,所以他将其修改为

decltype(**(Pointer*)0)
Run Code Online (Sandbox Code Playgroud)

我尝试了这个,但它确实有效,但后来我认为它看起来有点不确定因为它涉及空引用的解引用,因此可能不符合标准.

我们可以做得更好吗?

c++ templates c++11

19
推荐指数
1
解决办法
5091
查看次数

为什么std :: function不能绑定到C风格的可变参数函数?

例如,这无法编译:

std::function<decltype(printf)> my_printf(printf);

使用gcc,错误消息显示为:

error: variable 'std::function<int(const char*, ...)> my_printf' has initializer but incomplete type
     std::function<decltype(printf)> my_printf(printf);
Run Code Online (Sandbox Code Playgroud)

起初我以为这是gcc中的一个错误,但后来我看了标准,看起来这样就不支持了.这是什么技术原因?

c++ c++11

18
推荐指数
1
解决办法
2111
查看次数

在C ++ 17中,malloc是否返回“无效的指针值”?

根据C ++ 17 [basic.compound] / 3:

指针类型的每个值都是以下之一:

  • 指向对象或函数的指针(据说该指针指向对象或函数),或
  • 一个超出对象末尾的指针(8.7),或者
  • 该类型的空指针值(7.11),或者
  • 无效的指针值。

malloc函数返回一个指针值。让我们假设调用成功,因此返回值不为null。malloc([c.malloc])的规范没有声明它在返回的存储中创建了任何对象,因此似乎“无效的指针值”是最没有意义的类别。

c++ pointers object-lifetime language-lawyer c++17

16
推荐指数
2
解决办法
390
查看次数