将指向模板类调用的指针强制转换为同一模板的不同调用是否安全?

tim*_*rov 0 c++ templates casting

这里的动机是建立一个对数据进行操作的函数库,而不需要了解数据.在下面的示例中,test_me使用实际数据类型(int)调用窗口小部件模板.并派生一个小部件,作用于传递的数据.然后将它们传递给一个库例程,该例程将数据指针传递给虚拟act方法.

template <class T>
class widget
{
public:
  widget() {}
  virtual ~widget() {}
  virtual void act( T *p ) = 0;
};
class int_widget : public widget<int>
{
public:
  int_widget() : widget() {}
  virtual ~int_widget() {}
  virtual void act( int *p ) {
    printf( "*p=%d\n", *p );
  }
};
void pass_to( void *data, widget<void> *wvp )
{
  wvp->act( data );
}
void test_me()
{
  // we want to pass 42 to an int_widget...
  int i = 42;
  int_widget iw;
  // is this a safe way to do it?
  pass_to( (void *) &i, (widget<void> *) &iw );
}
Run Code Online (Sandbox Code Playgroud)

显然,图书馆的消费者承担责任,确保所有小部件都能正确地解释他们所提供的数据.

如果编译器以完全相同的方式为窗口小部件的各种调用布局vtable,则此方法有效.并且没有问题转换指向实际数据的指针.

问题是:我是否错过了除上述之外的任何条件?并且出于所有实际目的,上述假设是否有效?

Bat*_*eba 5

不,这不安全.不同的模板实例化是根本不同的类型.

通过void*从一个这样的类型到另一个类型的转换是未定义的行为.