小编cur*_*guy的帖子

使用带有多重继承的enable_shared_from_this

BI正在enable_shared_from_this我的代码中使用,我不确定它的用法是否正确.这是代码:

class A: public std::enable_shared_from_this<A>
{
public:
    void foo1()
    {
        auto ptr = shared_from_this(); 
    }
};

class B:public std::enable_shared_from_this<B>
{
public:
    void foo2()
    {
        auto ptr = shared_from_this(); 
    }
};

class C:public std::enable_shared_from_this<C>
{
public:
    void foo3()
    {
        auto ptr = shared_from_this(); 
    }
};

class D: public A, public B, public C
{
public:
    void foo()
    {
        auto ptr = A::shared_from_this(); 
    }
};
Run Code Online (Sandbox Code Playgroud)

这些用法是否make_shared_from_this()正确,假设它们总是被shared_ptrD 调用?

c++ multiple-inheritance shared-ptr c++11 enable-shared-from-this

21
推荐指数
1
解决办法
1万
查看次数

访问静态超出范围的未定义行为?

在与我的一位同事交谈时,他们说:

foo() {
    int *p;
    {
        int x = 5;
        p = &x;
    }
    int y = *p;
}
Run Code Online (Sandbox Code Playgroud)

创建未定义的行为,因为生命周期规则和范围规则未指定.

然而:

foo() {
    int *p;
    {
        static int x = 5;
        p = &x;
    }
    int y = *p;
}
Run Code Online (Sandbox Code Playgroud)

没有定义!您最终会遇到"间接范围"问题.

术语的使用听起来不正确.
我知道静态与范围无关.
第二种情况是否定义了行为?

c++ static scope lifetime undefined-behavior

21
推荐指数
1
解决办法
1017
查看次数

有没有办法使成员函数不能从构造函数中调用?

我有使用的成员函数(方法)

std::enable_shared_from_this::weak_from_this() 
Run Code Online (Sandbox Code Playgroud)

简而言之:weak_from_this返回weak_ptr这个。一个警告是它不能从构造函数中使用。如果有人使用继承的类的构造函数中的函数,则该函数weak_from_this将返回expired weak_ptr。我通过断言检查它是否未到期来进行防范,但这是运行时检查。

有没有一种方法可以在编译时进行检查?

c++ constructor shared-ptr weak-ptr c++17

21
推荐指数
2
解决办法
1493
查看次数

虚拟表C++

我读了很多人写的"一个虚拟表存在于一个已经在其中声明了虚函数的类".

我的问题是,vtable是仅存在于具有虚函数的类还是存在于从该类派生的类中.

例如

class Base{
    public:
        virtual void print(){cout<<"Base Print\n";}
};
class Derived:public Base{
    public:
        void print(){cout<<"Derived print\n";}
};

//From main.cpp 
Base* b = new Derived;
b->print();
Run Code Online (Sandbox Code Playgroud)

问题:如果没有派生类的vtable,那么输出就不会是"派生打印".所以IMO存在一个vtable,用于任何已声明虚函数的类,也存在于从该类继承的类中.它是否正确 ?

c++ virtual-functions derived-class vtable

20
推荐指数
1
解决办法
2万
查看次数

C++私有虚拟继承问题

在下面的代码中,似乎类C无法访问A的构造函数,这是因为虚拟继承所必需的.然而,代码仍然编译和运行.它为什么有效?

class A {};
class B: private virtual A {};
class C: public B {};

int main() {
    C c;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此外,如果我从A中删除默认构造函数,例如

class A {
public:
    A(int) {}
};
class B: private virtual A {
public:
    B() : A(3) {}
};
Run Code Online (Sandbox Code Playgroud)

然后

class C: public B {};
Run Code Online (Sandbox Code Playgroud)

会(意外地)编译,但是

class C: public B {
public:
    C() {}
};
Run Code Online (Sandbox Code Playgroud)

不会像预期的那样编译.

使用"g ++(GCC)3.4.4(cygming special,gdc 0.12,使用dmd 0.125)编译的代码",但已经验证它与其他编译器的行为相同.

c++ inheritance encapsulation virtual-inheritance private-inheritance

20
推荐指数
2
解决办法
3614
查看次数

如果void实际定义为`struct void {};`,那么现有的C++代码会破坏多少

void在C++类型系统中是一个奇怪的疣.这是一个不完整的类型,无法完成,它有各种有关限制方式的魔术规则:

类型cv void是不完整的类型,无法完成; 这种类型有一组空值.它用作不返回值的函数的返回类型.任何表达式都可以显式转换为cv void([expr.cast]).类型的表达式CV void应仅作为一个表达式语句,作为逗号表达式的操作数,作为一个第二或第三操作数?:([expr.cond]),作为操作数typeid,noexceptdecltype,如在表达return具有返回类型cv 的函数的语句void,或作为显式转换为cv 类型的操作数的语句void.

(N4778,[basic.fundamental]9)

除了对所有这些奇怪规则的痒感之外,由于它的使用方式有限,在编写模板时经常会出现一个痛苦的特殊情况; 通常情况下,我们希望它表现得更像std::monostate.


让我们想象一下,除了上面的引文,标准说的void是类似的东西

这是一个定义相当于以下类型的类型:

struct void {
    void()=default;
    template<typename T> explicit void(T &&) {}; // to allow cast to void
};
Run Code Online (Sandbox Code Playgroud)

保持void *魔法 - 可以别名任何对象,数据指针必须在往返过程中存活void *.

这个:

  • 应涵盖void"适当"类型的现有用例;
  • 可能允许删除关于它通过标准传播的相当数量的垃圾 - 例如[expr.cond]2可能是不需要的,[stmt.return]将大大简化(同时仍然保持"异常",return …

c++ language-design generic-programming void language-lawyer

20
推荐指数
1
解决办法
415
查看次数

为什么成员在此示例中未进行零初始化?

这特别是关于C++ 11:

#include <iostream>
struct A {
    A(){}
    int i;
};
struct B : public A {
    int j;
};
int main() {
    B b = {};
    std::cout << b.i << b.j << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

用g ++ 8.2.1编译:

$ g++ -std=c++11 -pedantic-errors -Wuninitialized -O2 a.cpp
a.cpp: In function ‘int main()’:
a.cpp:25:25: warning: ‘b.B::<anonymous>.A::i’ is used uninitialized in this function [-Wuninitialized]
     std::cout << b.i << " " << b.j << std::endl
Run Code Online (Sandbox Code Playgroud)

gcc检测b.i为未初始化,但我认为它应该与零一起进行零初始化b.j.

相信正在发生的事情(特别是C++ 11,来自ISO/IEC工作草案N3337,强调我的):

  • B …

c++ initialization language-lawyer c++11 list-initialization

20
推荐指数
2
解决办法
927
查看次数

to_address的特定用例

因此,显然C ++ 20正在得到std::to_address

从cppreference页面上,它的用例对我来说似乎并不明确。我们已经有了operator&std::addressof,为什么还需要另一个函数来为其参数提供地址?

c++ address-operator c++20

20
推荐指数
1
解决办法
773
查看次数

是POD类型完全等同于琐碎的标准布局类型吗?

在C ++ 20中,不赞成使用POD的概念,因为它是琐碎且标准的布局的无意义的合成特征。但是,C ++ 20草案中的POD定义并不完全是“琐碎的和标准布局”;实际上是:

POD类是既是普通类又是标准布局类的类,并且不具有非POD类类型的非静态数据成员(或其数组)。POD类型是标量类型,POD类,这种类型的数组或这些类型之一的cv限定版本。

换句话说,POD类型不仅是琐碎的而且是标准布局的,而且也是递归的。

该递归需求是否多余?换句话说,如果一个类型既是琐碎的又是标准布局,那么它是否也自动递归地变得琐碎又是标准布局?如果答案为“否”,那么标准布局,琐碎类型却不能成为POD的例子是什么?

c++ language-lawyer standard-layout c++20

20
推荐指数
2
解决办法
229
查看次数

是否将shared_ptr的删除器存储在自定义分配器分配的内存中?

说我有一个shared_ptr带有自定义分配器自定义删除器的。

我在标准中找不到任何内容讨论删除器的存储位置:它没有说自定义分配器将用于删除器的内存,也没有说不会

这是未指定的还是我只是缺少了什么?

c++ shared-ptr allocator language-lawyer c++17

20
推荐指数
2
解决办法
472
查看次数