小编Ayr*_*osa的帖子

据我所知,根据C++ 14中的§5.19/ 3和§5.19/ 2,这段代码不应该编译.

但它在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;

c++ language-lawyer constexpr c++14

7
推荐指数
1
解决办法
247
查看次数

main()下面的'i'类型.为什么它是int&?

我知道i下面的类型main()int&.这就是它必须初始化的原因.

int& f(){ static int i = 1; return i; }

int main()
{
    decltype(f()) i = f();
}
Run Code Online (Sandbox Code Playgroud)

但是使用5p5标准中的段落,我得出结论,表达式f()具有类型,int因为删除了引用.

7.1.6.2p4,如果f()从函数返回中删除了引用,怎么能说表达式是左值?

c++ decltype c++11

6
推荐指数
1
解决办法
278
查看次数

AFAIK,下面的代码不应该编译,但它在clang和GCC中.我在这里错过了什么?

下面的代码显示了一个类似联合的类,其中包含一个非平凡的默认构造函数(y使用大括号或大小写初始化成员),因此如果默认构造函数是默认构造函数,则应根据§删除它12.1/5第一个要点.也就是说,声明T t;不应该编译,因为没有默认的构造函数union T.但是代码在clang和GCC中编译和执行.

#include <iostream>
union T
{
    int y{1};
    float x;
    char c;
    T() = default;
};

int main()
{
    T t;
    std::cout << t.y << '\n';
}
Run Code Online (Sandbox Code Playgroud)

编辑

我的上述问题从一开始就是错误的,因为工会T 不是一个类似工会的阶级.我刚刚了解了C++ 11中的§9.5/ 8,它说:

工会状类是联合或具有匿名联合作为直接成员的类.类似联合的类X具有一组变体成员.如果X是联合,则其变体成员是非静态数据成员; 否则,其变体成员是作为X成员的所有匿名联合的非静态数据成员.

现在,请考虑下面的代码段.它不会编译,因为会删除union的默认构造函数.但我仍然,不知道§12.1/ 5中哪个要点对这个结果是负责任的.请注意,union不是类似联合的类,因此,§12.1/ 5中的第一个要点不适用.但这就是clang和GCC中的错误消息.查看实例.

#include <iostream>

union T{
    int y;
    struct A{ int i; A():i{1} {} } a;
};

int main()
{ …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++11

6
推荐指数
1
解决办法
548
查看次数

当我从虚拟基础派生D时,为什么在VS2015中sizeof(D)增加了8个字节?

我正在使用C++14§3.11/ 2中的示例:

struct B { long double d; };
struct D : virtual B { char c; }
Run Code Online (Sandbox Code Playgroud)

在clang,g ++和VS2015中运行下面的代码片段之后

#include <iostream>
struct B { long double d; };
struct D : /*virtual*/ B { char c; };

int main()
{
    std::cout << "sizeof(long double) = " << sizeof(long double) << '\n';
    std::cout << "alignof(long double) = " << alignof(long double) << '\n';

    std::cout << "sizeof(B) = " << sizeof(B) << '\n';
    std::cout << "alignof(B) = " << alignof(B) << …
Run Code Online (Sandbox Code Playgroud)

c++ alignment virtual-inheritance c++14

6
推荐指数
1
解决办法
274
查看次数

`f();`如何成为下面的声明?

DR 1990的摘录:

在一个例子中

void f() {
    f();  // #1
}
Run Code Online (Sandbox Code Playgroud)

#1处的语句不明确,可以解析为表达式或声明.

c++ declaration language-lawyer c++17

6
推荐指数
1
解决办法
197
查看次数

我在理解[basic.scope.pdecl] / 7时遇到了一些困难

[basic.scope.pdecl] / 7

首先elaborated-type-specifier中声明的类的声明要点如下:

(7.1)声明形式

          class-key attribute-specifier-seq opt 标识符 ;

         的识别符被声明为一个类名称在包含声明的范围,否则

(7.2)用于阐述型说明符的形式的

          类键 标识符

         如果在命名空间范围内定义的函数的decl-specifier-seqparameter-declaration-clause中使用了elaborated-type-specifier,则标识符将在包含该声明的命名空间中声明为类名;否则,除作为好友声明外,标识符在包含该声明的最小名称空间或块范围中声明。[?注意:这些规则也适用于模板。-?end note?] [?注:其他形式的 elaborated-type-specifier不会声明新名称,因此必须引用现有的type-name
         。请参阅[basic.lookup.elab]和[dcl.type.elab]。-?尾注?]

考虑上面的情况(7.2),其中在命名空间范围中定义的函数的参数声明子句decl-specifier-seq中使用了elaborated-type-specifier。这个精巧的类型说明符必须是该类在其命名空间中的第一个声明,这一事实如何与之相协调?

考虑下面的示例(demo):

档案prog.cc

struct S;
extern S s;
int S;
void f(struct S&);     // The elaborated-type-specififer `struct S` is not
                       // the first …
Run Code Online (Sandbox Code Playgroud)

c++ forward-declaration language-lawyer

6
推荐指数
1
解决办法
192
查看次数

cmap的Microsoft OpenType规范

OpenType文件中的cmap表将字符代码转换为字形ID.

任何人都可以帮助我理解C表达式:

*(idRangeOffset[i]/2 + (c - startCount[i]) + &idRangeOffset[i])
Run Code Online (Sandbox Code Playgroud)

是Format 4 cmap子表.

truetype

5
推荐指数
2
解决办法
1315
查看次数

在下面的代码片段中,C++标准中的"a = b + {1,2}"是不允许的?

a = b + {1, 2}以下禁止在标准中的哪个位置?

class complex {
    double re, im;
public:
    complex(double r, double i) : re{ r }, im{ i } {}
    complex& operator+=(const complex& other) { re += other.re; im += other.im; return *this; }
};

inline complex operator+(complex lhs, const complex& rhs)
{
    lhs += rhs;
    return lhs;
}

int main()
{
    complex a{ 1, 1 };
    complex b{ 2, -3 };
    a += {1, 3};          // Ok
    a = b + {1, 2}; …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

5
推荐指数
1
解决办法
185
查看次数

向窗口应用程序发送 WM_CHANGEUISTATE 后,当使用鼠标访问菜单时,助记符不会显示在系统菜单上

下面的代码将 WM_CHANGEUISTATE 发送到窗口过程本身,并带有参数:

LOWORD(wParam) = UIS_CLEAR

HIWORD(wParam) = UISF_HIDEACCEL

lParam = 0x00000000

当用鼠标左键单击窗口客户区时。

根据此博客雷蒙德陈本应被显示在系统菜单中的助记符,当菜单用鼠标访问。以下段落摘自这篇文章:

清除标志会显示相应的指标。例如,如果您有 UISF_HIDEFOCUS 的 UIS_CLEAR,这意味着您想要显示焦点指示器。

就我而言,我有一个 UISF_HIDEACCEL 的 UIS_CLEAR,这意味着我想显示菜单加速器。

如果您运行下面的代码并在应用程序客户区上用鼠标左键单击,您应该使加速器在系统菜单中可见,即使使用鼠标访问该菜单也是如此。但这不会发生,即,如果您通过左键单击窗口图标或右键单击窗口标题栏来激活系统菜单,则系统菜单中的助记符将不会显示。我错过了什么?

#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
    WNDCLASSEX  wndclassx;
    wchar_t szAppName[] = L"WM_CHANGEUISTATE";

    wndclassx.cbSize = sizeof(WNDCLASSEX);
    wndclassx.style = CS_HREDRAW | CS_VREDRAW;
    wndclassx.lpfnWndProc = WndProc;
    wndclassx.cbClsExtra = 0;
    wndclassx.cbWndExtra = 0;
    wndclassx.hInstance = hInstance;
    wndclassx.hIcon = 0;
    wndclassx.hCursor = LoadCursor(0, IDC_ARROW);
    wndclassx.hbrBackground …
Run Code Online (Sandbox Code Playgroud)

c c++ windows winapi

5
推荐指数
1
解决办法
518
查看次数

C++ 标准中的哪一段禁止将常量指针转换为非常量指针?

const char*C++ 标准中的哪一段禁止从实参到形参的转换char*?我知道这是正确的。我只是想知道标准中哪里有这样的规定?

#include <iostream>

std::string message("Hello");

void my_log(char* pchar) {
    std::cout << pchar << '\n';
}


void my_func(const std::string& message)
{
    my_log(const_cast<char*>((&message)->c_str()));     // Ok
    my_log((&message)->c_str());                        // Doesn't compile
}


int main() {
    my_func(message);
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处的实例。

c++ language-lawyer

5
推荐指数
0
解决办法
127
查看次数