#include <iostream>
#include <typeinfo>
using namespace std;
int main()
{
int s = 2;
unsigned int u = 3;
auto k = s + u;
if (typeid(k) == typeid(s))
cout << "signed" << endl;
else if (typeid(k) == typeid(u))
cout << "unsigned" << endl;
else
cout << "error" << endl;
}
Run Code Online (Sandbox Code Playgroud)
GCC的这个项目的输出是:
unsigned
Run Code Online (Sandbox Code Playgroud)
我很确定这是未定义的或实现定义的行为 - 但我似乎无法将这些点与标准连接起来.
你能告诉我它在标准中的位置吗?
我有一个派生自A类的B类.A声明一个静态字段f,B可能声明一个相同名称的类似字段.以下不起作用:
struct A { static int f; };
struct B : A { static int f; }; // A::f is different from B::f
struct C : A {}; // A::f is the same as C::f
BOOST_STATIC_ASSERT((&A::f != &B::f));
BOOST_STATIC_ASSERT((&A::f == &C::f));
Run Code Online (Sandbox Code Playgroud)
尽管理论上这些断言可以在编译时检查,但是由于常量表达式不能接受地址,所以它们是不允许的.
有没有办法在编译时进行这种检查工作?
在C++ 11中,我对类型之间的差异感到困惑T,reference to T因为它们适用于命名变量的表达式.具体考虑:
int main()
{
int x = 42;
int& y = x;
x; // (1)
y; // (2)
}
Run Code Online (Sandbox Code Playgroud)
x上面(1)中表达式的类型是什么?难道int还是lvalue reference to int?(它的值类别显然是一个lvalue,但这与它的类型是分开的)
同样y,上面(2)中表达式的类型是什么?难道int还是lvalue reference to int?
它在5.1.1.8中说:
[标识符主表达式]的类型是标识符的类型.结果是由标识符表示的实体.如果实体是函数,变量或数据成员,则结果是左值,否则为prvalue.
看来我可以在块作用域声明一个函数:
int main()
{
void f(); // OK
}
Run Code Online (Sandbox Code Playgroud)
但我无法定义它:
int main()
{
void f() {}; // ERROR
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,块作用域的函数声明有什么用?什么是用例?
我认为我缺少一些关于左值到右值标准转换的基本知识。
从 C++11 4.1 开始:
非函数、非数组类型 T 的左值可以转换为纯右值
所以我们声明一个变量x:
int x = 42;
Run Code Online (Sandbox Code Playgroud)
此范围内的表达式x现在是左值(因此也是左值)。它满足 4.1 中左值到右值转换的要求。
将左值到右值转换应用于表达式的上下文的典型示例是什么x?
内核在第一次进入时加载本机用户区Linux应用程序后,x86-64 CPU寄存器大多为零,除了具有通常含义的RSP和RIP之外,寄存器CS SS和R11都不为零:
cs 0x33 51
ss 0x2b 43
r11 0x200 512
Run Code Online (Sandbox Code Playgroud)
据我所知,CS和SS寄存器在x86-64上未使用,因为在长模式下我们有一个扁平的64位地址模型.
CS和SS寄存器是否意味着内核的任何内容?用户地区是否只是让他们一个人呆着?
R11中的初始512值是什么意思?
根据C++ 14标准,以下程序是否格式错误?
int f() { return 42; }
int main() {
(void)f();
}
Run Code Online (Sandbox Code Playgroud)
如果不是,丢弃值表达式中是否包含唯一的函数调用表达式?(注意,这是子表达式,而不是整个表达式语句)
C++枚举类型似乎是"默认可构造的":
enum UE { a=1, b, c };
enum class SE { a=1, b, c };
int main() {
UE ue;
SE se;
}
Run Code Online (Sandbox Code Playgroud)
如何从标准中解释这一点?
我的意思是 - 让我们说我们想要改变标准,使它们不是默认的可构造性.哪些条款会改变?
假设我有以下功能模板:
template<typename T>
void mutate(T& t) { /*...*/ }
Run Code Online (Sandbox Code Playgroud)
并且我有以下课程模板:
template<typename... Args>
class Processor {
std::tuple<Args...> tup;
// call mutate on the ith tuple element
void process(size_t i) {
mutate(std::get<i>(tup)); // ERROR
}
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的,因为的i参数process不是常量表达式。(它不能是一个常量表达式,因为i直到运行时才知道)
在不修改process或的签名的情况下mutuate,是否可以有效地完成这项工作?即我如何更改实现process以使其调用mutate的ith成员tup?
假设我有一个 unordered_map:
std::unordered_map<Key, BigObject> big_objects;
Run Code Online (Sandbox Code Playgroud)
哪里BigObject就像:
struct BigObject {
BigObject(P1, P2, P3); // <--- expensive
/*...*/
};
Run Code Online (Sandbox Code Playgroud)
我有一个Key k, 和一组BigObjects 构造函数的参数P1 p1,P2 p2和P3 p3。
如果big_objects已经包含k我什么都不想做。如果big_objects不包含K我想构造并插入BigObject(p1,p2,p3)
是否可以通过一次查找来完成此操作big_objects?
即如果密钥已经存在,将emplace或try_emplace构建?BigObject
更新
经过一些测试后,似乎emplace可以构建BigObject,但try_emplace不能?
IE
big_objects[k] = BigObject(p1,p2,p3) // insert k, k now present...
big_objects.emplace(k, p1, p2, p3); // does construct …Run Code Online (Sandbox Code Playgroud)