如何使用cout打印0x0a而不是0xa?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
Run Code Online (Sandbox Code Playgroud) C++ 14中的§5.19/ 3定义了一个整型常量表达式和一个转换后的常量表达式:
一个积分常量表达式是整体的或无作用域枚举类型的表达式,隐式转换为prvalue,其中所述转换后的表达式是一个核心常量表达式.[注意:这些表达式可以用作数组边界(8.3.4,5.3.4),比特字段长度(9.6),如果基础类型不固定(7.2),则作为枚举器初始化器,以及作为比对(7.6). 2).-end note] 转换后的常量类型表达式
T是一个表达式,隐式转换为类型的prvalueT,其中转换后的表达式是核心常量表达式,隐式转换序列仅包含用户定义的转换,左值到右值转换( 4.1),积分促销(4.5)和积分转换(4.7),而不是缩小转换(8.5.4).[注意:这些表达式可以在new表达式(5.3.4)中使用,如case表达式(6.4.2),如果基础类型是固定的(7.2),作为枚举器初始化器,作为数组边界(8.3.4),以及作为整数或枚举非类型模板参数(14.3). - 尾注]
也许我错过了一些东西,但我的第一印象是每个积分常量表达式都是转换后的常量表达式.
编辑
而且我也相信这一段中有错误:
代替:
A converted constant expression of type T is an expression, implicitly converted to a prvalue of type T, ...
它应该是:
A converted constant expression of type T is an expression, implicitly converted to a prvalue of an integral type, ...
此更改允许以下代码进行编译:
#include <iostream>
struct A { operator int() { return …Run Code Online (Sandbox Code Playgroud) 第一个代码段编译时没有任何警告(实例):
#include <iostream>
struct A {
constexpr A(): i(5){}
constexpr operator int() { return 5; }
int i;
};
int main() {
A a;
int b[a]{ 0, 1, 2, 3, 4 };
std::cout << b[4] << '\n';
}
Run Code Online (Sandbox Code Playgroud)
现在通过返回i转换运算符(实例)来改变上面的代码段:
constexpr operator int() { return i; }
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会警告说这b是一个VLA.
对我来说,这两个变体似乎都符合C++ 14中的段落§5.19[expr.const]/3.
下面的代码在编译GCC,铛和VS2017和表达a->i的return声明是由它的恒定值1.更换它是正确的说,因为这是有效的a是不是在表达ODR使用的a->i?
struct A
{
static const int i = 1;
};
int f()
{
A *a = nullptr;
return a->i;
}
Run Code Online (Sandbox Code Playgroud)
PS:我认为a是不在表达式ODR使用的a->i,因为它满足在"除非"条件[basic.def.odr/4,如下所示:
除非应用左值到右值转换(7.1)以产生不调用任何非平凡函数的常量表达式(8.6),否则
x其名称显示为可能已评估的表达式的变量将被ex使用.如果是object,是表达式的潜在结果集合的元素,其中应用了左值到右值的转换(7.1),或者是丢弃值表达式(8.2).exxxexeee
特别地,表达式ex == a是表达式的潜在结果集合的元素e == a->i,根据[basic.def.odr]/2(2.3),包含表达式ex,其中应用了左值到右值的转换e.
我从N4140的§5.19/ 2得到了这个例子:
constexpr int incr(int &n) {
return ++n;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,这不是一个constexpr功能.但是代码片段用clang和g ++编译.查看实例.我在这里错过了什么?
请考虑以下代码段:
#include <iostream>
union U{
U(): i(1) {}
int i;
int j = 2; // this default member initializer is ignored by the compiler
};
U u;
int main(){
std::cout << u.i << '\n';
std::cout << u.j << '\n';
}
Run Code Online (Sandbox Code Playgroud)
代码打印(参见实例):
1
1
Run Code Online (Sandbox Code Playgroud)
标准中的哪个部分表示U::j编译器忽略了该成员的默认成员初始值设定项?
请注意,根据[class.union.anon]/4,下面的联合不会编译,这是可以的.我因此期待上面的代码段也不能编译.
查看实例:
union U{
int i = 1;
int j = 2;
};
Run Code Online (Sandbox Code Playgroud) 本文档的第2.6节计算包含有以下段落:
如果该行扩展为以 a?<?token 开头并包括 a?>? 令牌,那么 ?<? 和第一个?>? 组合形成要包含的文件名。令牌之间的任何空格都减少到一个空格;然后在初始?<? 之后的任何空格被保留,但在结束之前的尾随空格?>? 被忽略。CPP 根据?angle-bracket includes 的规则搜索文件。
我知道这是实现定义的,但为什么 GCC 必须这样?我特别指的是上面突出显示的句子。
编辑
我刚刚注意到在上面引用的一段之前的第三段说如下:
定义宏时必须小心。
#define保存令牌,而不是文本。预处理器无法知道宏将用作 的参数#include,因此它生成普通标记,而不是标头名称。如果您使用双引号包含,这不太可能导致问题,它与字符串常量足够接近。 但是,如果您使用尖括号,您可能会遇到麻烦。
有谁知道这里指出了什么样的问题?
无论谁说这个问题都是一个问题的重复" 是否有一个特定的原因,为什么一个尾随返回类型不是一个完整的类的背景? "并不知道他/她在说什么.尾随返回类型不是类的完整类上下文的事实并不能解释为什么这个问题中的代码不能编译,尽管它解释了对另一个问题的答案中给出的代码的拒绝,特别是涉及的成员函数的代码的一部分qux,并baz如由OP说明.
为了澄清我的论点,即下面的代码是有效的,你必须考虑[expr.prim.this]中的第二个注释,它说:在trailing-return-type中,被定义的类不需要是完成以便访问类成员.稍后声明的类成员不可见.正如我foo之前bar在我的例子中所声明的,没有什么可以阻止编译器foo在trailing-return-type中访问bar.
请注意,@ NathanOliver 下面的注释基于以下猜想:foo下面的成员函数的内联定义只是语法糖.这需要从标准中的引用证明.我还没有找到.一旦产生了这个引用,我肯定会接受一个答案,认为代码没有编译,因为trailing-return-type不是类的完整类上下文.
struct Test {
auto foo() {}
auto bar() -> decltype(foo()) {}
};
prog.cc:3:32: error: use of 'auto Test::foo()' before deduction of 'auto'
3 | auto bar() -> decltype(foo()) {}
| ^
prog.cc:3:32: error: use of 'auto Test::foo()' before deduction of 'auto'
Run Code Online (Sandbox Code Playgroud)
如果具有使用占位符类型的声明的返回类型的函数没有非丢弃的返回语句,则推断返回类型,就好像在函数体的右括号处没有操作数的return语句一样.[例如:
auto f() { } // OK, …
例如,除非incr()声明,否则下面的代码不会编译constexpr:
int incr(int& n) {
return ++n;
}
constexpr int foo() {
int n = 0;
incr(n);
return n;
}
Run Code Online (Sandbox Code Playgroud)
看看C++ 14中的§7.1.5/ 3,我们有:
constexpr函数的定义应满足以下约束条件:
(3.1) - 它不应是虚拟的(10.3);
(3.2) - 其返回类型应为字面类型;
(3.3) - 每个参数类型应为文字类型;
(3.4) - 其函数体应为= delete,= default或不包含的复合语句(3.4.1) - asm-definition,
(3.4.2) - goto语句,
(3.4.3) - try-block,或
(3.4.4) - 非文字类型的变量的定义或静态或线程存储持续时间或未执行初始化的时间.
但它在gcc 4.9.0中编译.查看实例:
#include <iostream>
struct A {
constexpr A(): i(5) {}
int&& f() { return std::move(i); }
int i;
} a;
A&& f(A& a) { return std::move(a); }
int main() {
A a;
int b[a.f()]{ 0, 1, 2, 3, 4 };
std::cout << b[4] << '\n';
}
Run Code Online (Sandbox Code Playgroud)
从§5.19/ 3开始,我们有:
整数常量表达式是整数或未整数枚举类型的表达式,隐式转换为prvalue,其中转换后的表达式是核心常量表达式.[注意:这些表达式可以用作数组边界(8.3.4,5.3.4),比特字段长度(9.6),如果基础类型不固定(7.2),则作为枚举器初始化器,以及作为比对(7.6). 2). - 尾注]
表达式a.f()是整数类型的表达式.在我看来(虽然我需要对这一点进行一些澄清)这个表达式也可以转换为prvalue,因为它是一个xvalue.但是我觉得这里真正的问题是,表达a.f()是不是一个核心的常量表达式,它满足在§5.19/ 2弹点(2.1).
§5.19/ 2:
条件表达式
e是核心常量表达式,除非按照e抽象机器(1.9)的规则评估以下表达式之一:(2.1) -
this(5.1.1),除了constexpr作为一部分进行评估的函数或constexpr构造函数之外e;