gpt4 book ai didi

c++ - 静态断言基指针 "equals"是派生指针

转载 作者:搜寻专家 更新时间:2023-10-31 02:21:05 25 4
gpt4 key购买 nike

假设我有一个具有公共(public)基类的多态层次结构:

struct Base { ~virtual Base() = default; };

我继承了一个大型代码库,其中包含一长串访问器函数(每个派生类型一个),这些函数通过 reinterpret_cast 获取派生指针:

Derived * Get()       // Derived inherits from Base
{
Base * b = lookup_derived();
return reinterpret_cast<Derived *>(b);
}

显然,代码应该使用 static_castdynamic_cast(取决于基础是否是虚拟的)。但是,由于这个翻译单元很大,而且所有派生类的定义加起来也很大,所以 TU 中没有包含 Derived 的定义,只有它的声明。

我想通过向每个派生类定义添加一个静态断言来使此代码更加健壮,该断言表明此重新解释转换将产生正确的结果。本质上,我想要这样的东西:

struct Derived : Base
{
static_assert(static_cast<Derived *>(std::declval<Base *>()) ==
reinterpret_cast<Derived *>(std::declval<Base *>()));

// ...
};

这种构造当然不起作用,因为不能对 declval 求值,并且重新解释转换的结果不是常量表达式。是否有任何标准的 C++ 机制来静态执行此类测试? (另一种方法是在类构造函数中对 this 进行运行时检查。)

编辑:根据 Aaron 的帖子,我突然想到这个问题可以完全不用 reinterpret_casts 来表达:

static_cast<void *>(std::declval<Derived *>()) ==
static_cast<void *>(static_cast<Base *>(std::declval<Derived *>()))

最佳答案

我不确定这是否适合您的设置,但是 this code on ideone对我有用(clang 3.5.0 和 g++ 4.9.3)。

已更新为朝另一个方向转换,即Derived* -到- Base* , 以更紧密地匹配问题。并更新为使用 static_cast<void*>显式地代替 C 风格的转换和 reinterpret_cast .

template<typename D, typename B>
struct CheckCasting {
static D d_static;

constexpr
static B* bp = &d_static; // the original object is D,
// that allows us to static_cast both ways

static
constexpr bool static_equals_reinterpret() {
return static_cast<void*>(static_cast<D*>(bp))
== static_cast<void*>( bp );
}
};

struct Base {
constexpr Base() : i(0) {}
int i;
};

struct derived_with_virtual : public Base {
derived_with_virtual() {}
virtual void foo() { }
};
struct without_virtual : public Base {
without_virtual() {}
};

static_assert( ! CheckCasting<derived_with_virtual, Base> :: static_equals_reinterpret() ,"");
static_assert( CheckCasting<without_virtual , Base> :: static_equals_reinterpret() ,"");

一些评论:

  • 我尝试将类型转换替换为 void*使用 reinterpret_cast,但 clang 不喜欢那样。 “注意:常量表达式中不允许使用 reinterpret_cast”。
  • 我尝试移动 static_assert在派生类中没有成功。
  • 这需要为每个派生类静态分配一个对象。

关于c++ - 静态断言基指针 "equals"是派生指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31878000/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com