小编Wal*_*ldB的帖子

C++ 11标准中的§12.3.2/ 1似乎存在矛盾

C++ 11标准§12.3.2/ 1(强调我的):

成员函数具有以下形式的名称没有参数的类X的

conversion-function-id:

operator convert-type-id

conversion-type-id:

type-specifier-seq conversion-declarator

转换声明者:

ptr-operator转换声明器

指定从X到convert-type-id指定的类型的转换.这些功能称为转换功能.不能指定返回类型.如果转换函数是成员函数,则转换函数的类型(8.3.5)是"不返回convert-type-id的参数的函数".

转换函数是否始终是成员函数,或者有些情况不是这样?

c++ language-lawyer c++11

32
推荐指数
2
解决办法
1786
查看次数

我的假设是以下格式错误的NDR?但为什么?

[class.mem] / 6

一个类的完整类上下文是
(6.1)函数体,
(6.2)默认参数,
(6.3)noexcept-specifier([except.spec]),
(6.4)合同条件或
(6.5)默认成员初始化器

在类的成员规范内。[?注意:如果嵌套类是在封闭类的成员规范内定义的,则嵌套类的完整类上下文也是任何封闭类的完整类上下文。-?尾注?]

上面突出显示的文本似乎为以下代码段提供了支持:

#include<iostream>
struct A{
    int i = j + 1;
    int j = 1;
};

int main(){
    A a;
    std::cout << a.i << '\n';
    std::cout << a.j << '\n';
}
Run Code Online (Sandbox Code Playgroud)

,并且我希望它能打印出来

2
1
Run Code Online (Sandbox Code Playgroud)

无论GCC和铛打印

1
1
Run Code Online (Sandbox Code Playgroud)

但另外clang发出以下警告:

prog.cc:3:13: warning: field 'j' is uninitialized when used here [-Wuninitialized]
    int i = j + 1;
            ^
prog.cc:8:7: note: in implicit default constructor for 'A' first required here
    A …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer

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

我认为下面的陈述不正确或者我错过了什么?

下面的段落摘自Stroustup的书"The C++ Programming Language"(第三版)第420页:

因为指向虚拟成员的指针(在此示例中为s)是一种偏移量,所以它不依赖于对象在内存中的位置.因此,只要在两者中使用相同的对象布局,就可以安全地在不同的地址空间之间传递指向虚拟成员的指针.与普通函数的指针一样,指向非虚拟成员函数的指针不能在地址空间之间交换.

我在争论本段最后一句话.下面,您将找到一个代码片段,其中指向非虚拟成员函数的指针,foo()以及foo1()在一个基础对象a和派生对象之间交换b,没有问题.

不能做的是重载,基类中的任何函数,foo()或者foo1()在派生类中,在这种情况下,编译器将发出错误,如下所示.

#include <iostream>

class A
{
    int i;
    public:
    A() : i(1) {}
    void foo() { std::cout << i << '\n'; }
    void foo1() { std::cout << 2 * i << '\n'; }
};

class B: public A
{
    int j;
    public:
    B() : A(), j(2) {}
//  void foo() { std::cout << j << '\n'; }
};

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

c++

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

trailing-return-type中占位符类型的用途是什么?

根据[dcl.fct]/2,下面的代码段是合法的.GCC和clang编译并执行代码,

#include <iostream>
int i = -1;
auto f()->auto&& { return i; }
int main(){
    f() = 2;
    std::cout << i << '\n';
}
Run Code Online (Sandbox Code Playgroud)

印花

2
Run Code Online (Sandbox Code Playgroud)

但是在C++中允许这个的目的是什么?

在上面的示例中,只需将trailing-return-type替换为,就可以获得相同的结果int&.换句话说,我正在寻找一个示例,其中包含占位符类型的trailing-return-type将是有意义的.

c++ language-lawyer

6
推荐指数
2
解决办法
215
查看次数

为什么MS在win32api中没有一个返回字体文件名的函数,给定字体句柄?

这是第一次,在使用Windows API的多年经验中,我遇到了一种情况,我需要做一些事情,我不能用Windows当前的编程接口.

根据我的研究,字体"Arial Black"使用该文件,arialblk.ttf并且字体"Arial Black Italic"没有文件,也没有字体"Arial Black Bold",至少在我的Windows 7计算机中.

我插入一个程序下方,用单独的字体"Arial Black"显示几行文字,然后用斜体和粗体显示.令我惊讶的是,斜体文本正常呈现,粗体文本呈现为"Arial Black".然后我意识到MS Word也会发生同样的事情.我还插入了Word文档的屏幕截图,由下面的代码输出叠加.这里发生了什么事 ?我是否必须猜测,在每种情况下使用哪个字体文件?显然Windows API没有给我答案的可能性.为何如此神秘?

#include <Windows.h>

LRESULT CALLBACK WndProc(HWND, UINT, UINT, LONG);


int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int nCmdShow)
{
    WNDCLASSEX  wndclassx;

    wndclassx.cbSize        = sizeof(WNDCLASSEX);
    wndclassx.style         = CS_HREDRAW | CS_VREDRAW;
    wndclassx.lpfnWndProc   = WndProc;
    wndclassx.cbClsExtra    = 0;
    wndclassx.cbWndExtra    = 0;
    wndclassx.hInstance     = hInstance;
    wndclassx.hIcon         = nullptr;
    wndclassx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wndclassx.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wndclassx.lpszMenuName  = nullptr;
    wndclassx.lpszClassName = L"WndProc";
    wndclassx.hIconSm       = nullptr; …
Run Code Online (Sandbox Code Playgroud)

c++ winapi fonts windows-7

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

下面的代码片段在发布版本中发生了什么?

下面的代码生成一个悬空引用,可以在编译器发出的警告中看到,并且在函数返回之前调用A函数中对象的析构g()函数.还可以验证在main()"使用堆栈"之后,返回的引用具有垃圾,至少在调试版本中是这样.但我无法在发布版本中重现相同的行为.这是为什么?编译器在这里做了什么样的优化,给人的印象是引用r是OK?

#include <iostream>

struct A{
    A(int i) : i(i) { std::cout << "Ctor\n"; }
    A(const A& a) { i = a.i; std::cout << "Copy ctor\n"; }
    ~A() { std::cout << "Dtor\n"; }
    int i;
};

A& g(int i) { A x(i); return x; }

int main()
{
    const A& r = g(1);
    std::cout << "Using the stack\n";     
    std::cout << r.i << '\n';   // r.i has garbage in debug, but not in a …
Run Code Online (Sandbox Code Playgroud)

c++

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

为什么模板类的成员需要通过其模板类的参数进行参数化

在Stroustrup的书(第4版 - 第一次打印)的第668页中,您将找到以下模板类示例?

template<typename C>
class String{
public:
    String();
    ...
private:
    int sz;
    C* ptr;
};
Run Code Online (Sandbox Code Playgroud)

在第679页中,作者写道:

模板类的成员本身是由其模板类的参数参数化的模板.当这样的成员在其类之外定义时,它必须明确声明为模板.例如:

template<typename C>
String<C>::String()
    :sz(0), ptr(ch)
{
    ch[0] = {}; 
}
Run Code Online (Sandbox Code Playgroud)

这个例子中有一个明显的错误.变量ch 在上面没有任何意义.但这与我的问题无关.我想知道的是为什么没有参数就无法定义上面的构造函数C,如下所示?

template<typename C>
String::String()
    : sz(0), ptr(nullptr)
{
}
Run Code Online (Sandbox Code Playgroud)

c++ templates

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

[basic.lookup.unqual]/3中的第一个例子

[basic.lookup.unqual]/3中的第一个例子:

int h;
void g();
namespace N {
  struct A {};
  template <class T> int f(T);
  template <class T> int g(T);
  template <class T> int h(T);
}

int x = f<N::A>(N::A());        // OK: lookup of f finds nothing, f treated as template name
int y = g<N::A>(N::A());        // OK: lookup of g finds a function, g treated as template name
int z = h<N::A>(N::A());        // error: h< does not begin a template-id
Run Code Online (Sandbox Code Playgroud)

上面的注释似乎表明编译器应该对名称gh上面的查找进行不同的处理,就好像模板ID不会被考虑用于名称一样 …

c++ language-lawyer

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

4
推荐指数
1
解决办法
124
查看次数

下面的代码无法编译.也许是因为带有std = c ++ 2a的GCC仍然没有与最新的草案完全一致

[class.mem]/6:

一个完整的类的上下文是一个

(6.1)函数体,(6.2)默认参数,(6.3) noexcept-specifier([except.spec]),(6.4)合同条件,或(6.5)默认成员初始化程序

在类的成员规范内.[注意:如果嵌套类在封闭类的成员规范中定义,则嵌套类的完整类上下文也是任何封闭类的完整类上下文. - 结束说明]

该段落在草案中引入了拉动请求#2231.

据我所知,根据上面的注释,下面的代码应该编译.但事实并非如此.我假设GCC编译器仍然不是最新的草案.我是否正确,或者我对此笔记的理解是否正确?

struct A {
    int i = 1;
    struct B { 
        int j = 2;
        int f() {
            return i + j;
        }
    };
};
Run Code Online (Sandbox Code Playgroud)

哪个失败了:

source>: In member function 'int A::B::f()':
<source>:6:20: error: invalid use of non-static data member 'A::i'
    6 |             return i + j;
      |                    ^
<source>:2:9: note: declared here
    2 |     int i = 1;
      | …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++20

0
推荐指数
1
解决办法
126
查看次数

标签 统计

c++ ×10

language-lawyer ×6

c++11 ×1

c++20 ×1

fonts ×1

templates ×1

winapi ×1

windows-7 ×1