小编gez*_*eza的帖子

在C++ 11中std :: sin的变化?

cppreference包括以下关于返回值的std::sin描述:

如果arg的大小很大,那么结果可能很少或没有意义(直到C++ 11)

我试图在当前的C++标准中找到有关这方面的信息,但我什么也没发现(也许我错过了它?).这方面C++ 11究竟发生了哪些变化std::sin

c++ c++11

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

如果事后定义了类型,那么实例化一个格式不正确的类模板吗?

这段代码肯定是格式错误的,因为它Foo是在实例化点之后专门化的:

template <typename T>
struct Foo {
    int a;
};

Foo<int> x = { 42 };

template <>
struct Foo<int> {
    const char *a;
};

Foo<int> x = { "bar" };
Run Code Online (Sandbox Code Playgroud)

由于我强调的标准部分,它形成不良:

函数模板,成员函数模板或类模板的成员函数或静态数据成员的特化可以在翻译单元内具有多个实例化点,并且除了上述实例化的点之外,对于任何这样的实例化.在翻译单元内具有实例化点的专门化,翻译单元的末尾也被认为是实例化的点.类模板的专门化在翻译单元中最多只有一个实例化点.任何模板的特化可以在多个翻译单元中具有实例化点.如果两个不同的实例化点根据单定义规则给出模板特化的不同含义,则程序形成错误,不需要诊断.

现在,这个代码是不正确的吗?

struct A;

template <typename> class Foo { };

Foo<A> foo; // note A is incomplete here

struct A {};
Run Code Online (Sandbox Code Playgroud)

如果这样Foo宣布,那么不良形象会改变吗?

struct A;

template <typename T>
struct Foo {
    Foo() {
        new T;
    }
};

Foo<A> foo; // …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++17

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

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

布局兼容类型的联合

看看这段代码:

struct A {
    short s;
    int i;
};
struct B {
    short s;
    int i;
};

union U {
    A a;
    B b;
};

int fn() {
    U u;
    u.a.i = 1;
    return u.b.i;
}
Run Code Online (Sandbox Code Playgroud)

是否保证fn()退货1

注:这是一个后续问题要这个.

c++ unions language-lawyer standard-layout c++17

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

什么使工会会员活跃?

什么使工会会员活跃?

我已经阅读了C++ 14标准的第9.5章(关于工会的第9.5章),但我还没有找到一个明确的答案,让工会成员活跃起来.

有一个说明:

通常,必须使用显式析构函数调用和放置新运算符来更改联合的活动成员.

所以,例如,

union U {
  int i;
  short s;
} u;

new(&u.i) int(42);
Run Code Online (Sandbox Code Playgroud)

好的,放置新的更改活动成员,很明显.但是在处理具有普通构造函数的类型时,我们通常不使用placement new.

是否operator=更改,恕不UB活动成员?

u.i = 42;
Run Code Online (Sandbox Code Playgroud)

在这里,operator=调用一个未构造的对象.它定义明确吗?

那这个呢?

struct A {
  int i0;
  int i1;
};
union U {
  A a;
  short s;
} u;
Run Code Online (Sandbox Code Playgroud)

是什么使其a成为活跃的成员u?设置两个i0&i1足够吗?

u.a.i0 = 42;
u.a.i1 = 99;
Run Code Online (Sandbox Code Playgroud)

如果我写的怎么办:

u.a.i0 = 42;     // supposedly this doesn't change the active member to a, as i1 isn't set
int …
Run Code Online (Sandbox Code Playgroud)

c++ unions language-lawyer c++14 c++17

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

是否可以自动定义变量静态或非静态,具体取决于初始化是否为constexpr?

假设我有一个类型:

struct Foo {
    int a, b, c, d, e;
};
Run Code Online (Sandbox Code Playgroud)

现在,我想要一个宏(或任何其他解决方案),它可以Foo以某种方式定义一个对象,如果该对象可以constexpr(因为它是用编译时初始化int的),那么它将其定义为static constexpr Foo.如果不能constexpr,那么它定义为const Foo(我在函数范围内使用此宏).

所以,我想要一个宏(或一些等效的解决方案):

#define DEF(a, b, c, d, e) ... // magic here
Run Code Online (Sandbox Code Playgroud)

如果我用编译时常量调用它:

DEF(1, 2, 3, 4, 5);
Run Code Online (Sandbox Code Playgroud)

然后我想将其扩展为:

static constexpr Foo foo{1, 2, 3, 4, 5};
Run Code Online (Sandbox Code Playgroud)

但是,如果任何参数不是编译时常量(所以它不能constexpr):

int b = 2;
DEF(1, b, 3, 4, 5); // second parameter is not a compile-time constant
Run Code Online (Sandbox Code Playgroud)

然后我想:

const Foo foo{1, b, 3, 4, …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

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

如果没有使用 odr,为什么变量会引用 lambda 之外的变量?

看这个例子(godbolt):

\n
void foo(int &par) {\n    auto l = [par]() {\n        decltype(par) x;\n    };\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这个程序无法编译,因为parindecltype(par)引用的是 in 的参数foo,而不是 lambda 的变量(所以decltype(par)实际上是一个引用类型,需要初始化)。

\n

这是 C++14 标准的相关引用(很抱歉引用旧标准,但我认为它更容易理解)。

\n

expr.prim.lambda/18(重点是我的):

\n

“lambda 表达式的复合语句中的每个 id 表达式(通过复制捕获的实体的 odr 使用)都会转换为对闭包类型的相应未命名数据成员的访问。[注:id 表达式这不是 odr-use 指的是原始实体,而不是闭包类型的成员。此外,这样的 id 表达式不会导致实体的隐式捕获。 \xe2\x80\x94 尾注]"

\n

标准确保如果 decltype 在非 id 表达式上使用,那么即使它不使用该变量,也会使用捕获的变量(expr.prim.lambda/19):

\n

“decltype((x)) 的每次出现(其中 x 可能是一个带括号的 id 表达式,它命名了自动存储持续时间的实体)被视为 x 被转换为对闭包类型的相应数据成员的访问,该数据成员本来可以被如果 x 是指定实体的 ODR 使用,则声明。”

\n

因此,根据这些规则(也许该标准还有其他相关规则),lambda 中的变量可能引用捕获的变量,也可能引用封闭函数中的原始变量。

\n

我有两个问题:

\n …

c++ lambda language-lawyer c++14

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

int main(void)在C++中有效吗?

C++标准列出了允许的形式main.它不会int main(void)列为允许的表单.但是,它通常表明这一点

参数列表(void)等效于空参数列表

int main(void)允许的形式?

c++ language-lawyer

9
推荐指数
1
解决办法
356
查看次数

当编译器没有看到可以实现转换的可能类型时,是否允许编译器优化volatile指针的dynamic_cast?

看看这个小片段:

struct A {
    virtual ~A() { }
};

struct B { };

bool fn() {
    A *volatile a = new A;
    return dynamic_cast<B *>(a); 
}
Run Code Online (Sandbox Code Playgroud)

编译器是否允许dynamic_cast完全删除,并转换dynamic_cast为简单nullptr;

这个问题的原因是这个答案.

笔记:

  • 假设volatile意味着编译器不能假设任何东西a,因为它是volatile.这是一个问题的原因.

  • dynamic_cast可能不被允许删除的事实是程序中某处可能存在某种类型,它来源于AB.

c++ dynamic-cast volatile language-lawyer

9
推荐指数
1
解决办法
219
查看次数

转换为无符号时,标准表示"最无符号整数"是结果.为什么"最不重要"在这里很重要?

C++标准在[conv.integral/2]中说,关于整数转换为无符号:

如果目标类型是无符号的,则结果值是与源整数一致的最小无符号整数(模2 n ,其中n是用于表示无符号类型的位数).

我的问题是,为什么" 最少 " 这个词在那里?是否可能有多个结果,我们需要从中选择一个?

c++

9
推荐指数
1
解决办法
163
查看次数