相关疑难解决方法(0)

如何从非多态虚拟基类转发?

当没有涉及虚函数时,有没有办法从虚拟基类转发到派生类?这里有一些代码来演示我在说什么:

struct Base1
{
  int data;
};

struct Base2
{
  char odd_size[9];
};

struct ViBase
{
  double value;
};


struct MostDerived : Base1, Base2, virtual ViBase
{
  bool ok;
};


void foo(ViBase &v)
{
  MostDerived &md = somehow_cast<MostDerived&>(v);  //but HOW?
  md.ok = true;
}


int main()
{
  MostDerived md;
  foo(md);
}
Run Code Online (Sandbox Code Playgroud)

请注意,该代码仅用于演示.我的真实场景相当复杂,涉及模板参数和从一个到另一个的转换,只知道第一个是第二个的基础; 它可以是普通或虚拟的基础,它可能有也可能没有虚函数.(参见底部的简化示例).我可以使用类型特征检测多态情况和虚拟/非虚拟基本情况,并解决除非多态虚拟基础之外的所有情况.这就是我要问的问题.

我真的想不出一种做演员的方法:

  • 隐含的转换是正确的; 这些只做了预告.

  • static_cast 明确禁止从虚拟基类进行转换:

    5.2.9/2 ...并且B既不是虚拟基类,D也不是虚基类的基类D....

  • dynamic_cast 也不能这样做,因为downcast需要一个多态类

    5.2.7/6否则,v应该是指向多态类型的指针或glvalue(10.3).

    10.3/1 ...声明或继承虚函数的称为多态类.

  • reinterpret_cast 在这里根本不适用.

如果 …

c++ virtual-inheritance downcast

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

C++ 中 std::shared_ptr 的克隆模式

为什么需要(为了使其编译)中间体CloneImplementationstd::static_pointer_cast(参见下面的第3节)使用克隆模式std::shared_ptr而不是更接近(参见下面的第2节)使用原始指针(参见下面的第1节)?因为据我所知,std::shared_ptr有一个广义的复制构造函数和一个广义的赋值运算符?

1. 带有原始指针的克隆模式

#include <iostream>

struct Base {
    virtual Base *Clone() const {
        std::cout << "Base::Clone\n";
        return new Base(*this);
    }
};

struct Derived : public Base {
    virtual Derived *Clone() const override {
        std::cout << "Derived::Clone\n";
        return new Derived(*this);
    }
};

int main() {
  Base *b = new Derived;
  b->Clone();
}
Run Code Online (Sandbox Code Playgroud)

2. 共享指针的克隆模式(幼稚的尝试)

#include <iostream>
#include <memory>

struct Base {
    virtual std::shared_ptr< Base > …
Run Code Online (Sandbox Code Playgroud)

overriding clone virtual-functions smart-pointers c++11

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

什么时候指向数组的指针可以转换为不同类型的指针数组?

我正在查看cppreference文档,std::unique_ptr并注意到C++ 17似乎已经做了一些有趣的更改.特别是,std::unique_ptr<T[]>现在的特化接受模板参数,它之前只接受std::unique_ptr::pointer参数.例如,以下是其中一个reset成员函数的声明std::unique_ptr<T[]>:

template <typename U> void reset(U p);
Run Code Online (Sandbox Code Playgroud)

该网站声明:

行为一样的reset主模板的成员,但它只会参与重载分辨率如果任 U是相同的类型pointer,或者 pointer是相同的类型element_type*U是指针类型V*,使得V(*)[]可转换为element_type(*)[].

我假设这是为了安全 - 你不想delete[]在指向指向其基类型指针的派生类型数组的指针上执行(在C++ 17之前,这被标记为已删除) .正如所料,此代码编译良好:

#include <type_traits>

struct foo {};
struct bar : public foo {};
static_assert(!std::is_convertible_v<bar(*)[], foo(*)[]>);
Run Code Online (Sandbox Code Playgroud)

然而,有趣的是,以下内容无法编译,两者都失败static_assert:

#include <type_traits>

struct foo {};
struct bar : public foo {};
static_assert(std::is_convertible_v<bar*(*)[], foo*(*)[]>);
static_assert(std::is_convertible_v<std::unique_ptr<bar>(*)[], std::unique_ptr<foo>(*)[]>); …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

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