c++ - 成员指针的大小和 reinterpret_cast 是否固定?

标签 c++ c++11 delegates standards-compliance reinterpret-cast

我正在尝试创建一个模板类,其中包含指向任意类实例和函数的指针,如下所示:

template<class C>
class A {
   typedef void (C::*FunctPtr)(); //e.g. void C::some_funct();

   FunctPtr functPtr_;
   C* instPtr_;
public:
   A(FunctPtr functPtr, C* instPtr)
      : functPtr_(functPtr)
      , instPtr_(instPtr) {}
};

但是,我希望能够在不使用 placement new 进行动态内存分配的情况下创建此类的实例。 C++ 标准是否保证此模板类对于所有 C 类都具有固定大小?

Don Clugston's article关于指针,我注意到各种编译器上的成员函数指针的各种大小的图表,一些编译器的大小并不总是相同。我以为我被冲洗了,但这个标准符合吗?来自 C++ 标准 sec。 5.2.10 关于重新解释:

——将“指向成员函数的指针”类型的纯右值转换为指向成员函数的不同指针 类型并返回其原始类型产生指向成员值的原始指针。

C++ 标准中的语句是否表示成员函数指针的大小都相同?

如果不是,我想我仍然可以重写代码如下,以明确利用 reinterpret_cast 保证:

class GenericClass;

template<class C>
class A {

   typedef void (GenericClass::*GenFunctPtr)();
   typedef void (C::*SpecificFunctPtr)();

   GenFunctPtr functPtr_; //store any kind of function ptr in this fixed format
   GenericClass* instPtr_;

public:
   A(SpecificFunctPtr functPtr, C* instPtr)
      : functPtr_(reinterpret_cast<GenFunctPtr>(functPtr))
      , instPtr_(reinterpret_cast<GenericClass*>(instPtr)) {}

   void DoSomething()
   {
      //now convert pointers back to the original type to use...
      reinterpret_cast<SpecificFunctPtr>(functPtr_);
      reinterpret_cast<C*>(instPtr_);
   }
};

现在似乎要求所有尺寸都相同,但要符合标准,对吧?我更喜欢第一个选项,但是如果我必须,第二个也可以。想法?

最佳答案

我不知道标准中是否指定了成员指针的实现细节(找不到它),但由于我们知道 C* 将具有相同的大小对于所有的 C,我们可以只确定各种类型 CFunctPtr 的大小,然后添加一个 static_assert:

template <class C>
class A {
   typedef void (C::*FunctPtr)(); //e.g. void C::some_funct();
   static_assert(sizeof(FunctPtr) == 16, 
       "unexpected FunctPtr size"); // from coliru, clang and gcc

   FunctPtr functPtr_;
   C* instPtr_;
   ...
};

至少我尝试了几种类型的类({base, derived, multiple derived} x {virtual, non-virtual})并且它总是给出相同的大小。

这可能是特定于平台和/或编译器的,如Pointers to member functions are very strange animals表示:

The size of a pointer-to-member-function of a class that uses only single inheritance is just the size of a pointer.
The size of a pointer-to-member-function of a class that uses multiple inheritance is the size of a pointer plus the size of a size_t.

这不是我在 clang 或 gcc 中看到的。

关于c++ - 成员指针的大小和 reinterpret_cast 是否固定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29457915/

相关文章:

c++ - OpenCV 归一化函数,结果总和不为一

c++ - 如何在OpenCV中将平行四边形图像转换为矩形图像?

c++ - std::string 参数的右值

c++ - std::vector 在 push_back 期间多次调用析构函数?

linq - 在 where 子句中委托(delegate)

c++ - C++中链表的结构体定义

c++ - 为什么每次执行时函数的地址都不同?

c++ - 如何从 C++ 程序中打开进程并将结果读入 ifstream?

Objective-C:这个委托(delegate)在哪里声明,以及其他查询

c# - 模拟事件处理器