gpt4 book ai didi

c++ - 指向对象开头的指针 (C++)

转载 作者:太空狗 更新时间:2023-10-29 23:09:50 24 4
gpt4 key购买 nike

我需要一种方法来获取指向 C++ 中对象开头的指针。此对象在模板内使用,因此它可以是任何类型(多态或非多态),并且可能是使用多重继承的对象。

我找到了 this article它描述了一种在 T 是多态类型的情况下使用 typeid 和 dynamic_cast 到 void* 的方法(参见“动态转换”部分)。

这在 MSVC 上运行得非常好,但是在 GCC (4.x) 上,当它与非多态类型一起使用时,它似乎落在了它的屁股上并吐出编译器错误。

有没有人知道一种方法:

  • 让 GCC 自行运行,并正确评估 typeid
  • 或者另一种方法,将在 GCC 上编译

下面是我目前用来尝试实现此目的的代码。

template <typename T>
void* dynamicCastToVoidPtr(T *const ptr)
{
// This is done using a separate function to avoid a compiler error on some
// compilers about non-polymorphic types when calling startOfObject
return dynamic_cast<void*>(ptr);
}

template <typename T>
void* startOfObject(T *const ptr)
{
// In cases of multiple inheritance, a pointer may point to an offset within
// another object
// This code uses a dynamic_cast to a void* to ensure that the pointer value
// is the start of an object and not some offset within an object
void *start = static_cast<void*>(ptr);
if(start)
typeid(start = dynamicCastToVoidPtr(ptr), *ptr);
return start;
}

template <typename T>
void doSomethingWithInstance(T *const instance)
{
// Here is where I need to get a void* to the start of the object
// You can think of this as the deleteInstance function of my memory pool
// where the void* passed into freeMemory should point to the
// start of the memory that the memory pool returned previously
void *start = startOfObject(instance);
if(start)
allocator->freeMemory(start);
}

谢谢。

最佳答案

gcc 的确切错误信息是

error: cannot dynamic_cast &n (of type struct N*) to type void* (source type is not polymorphic)

这可以通过使用 boost::is_polymorphic 结合 boost::enable_ifboost::disable_if 来处理,不幸的是 gcc 阻塞了使用显而易见的方法,所以这里是解决方法:

template <class T>
void* address_of_impl(T* p, boost::enable_if< boost::is_polymorphic<T>, int >)
{
return dynamic_cast<void*>(p);
}

template <class T>
void* address_of_impl(T* p, ...) { return static_cast<void*>(p); }

template <class T>
void* address_of(T* p) { return address_of_impl(p, 0); }

我们使用 SFINAE 对我们有利(省略号总是在重载决策中被认为是最后一个,因此编译器首先尝试使用 dynamic_cast 版本,由于 enable_if< 而对于非多态类型失败)。

我已经在 gcc 3.4 上测试过了,它通过了。我正在调查 another question为什么使用 disable_if 而不是 ... 不起作用。

编辑:

这是一个简单的错字(忘记了 ::type 位):

template <class T>
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p) { return dynamic_cast<void*>(p); }

template <class T>
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type
address_of(T* p) { return static_cast<void*>(p); }

关于c++ - 指向对象开头的指针 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3488048/

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