【问题标题】:Weird error of compilation of template specialization of SingletonSingleton模板特化编译的奇怪错误
【发布时间】:2012-03-27 09:45:14
【问题描述】:

我对使用类和函数作为参数的模板有疑问。 问题是,当仅声明和定义 AAInterceptor 时,它可以正常工作。当我添加 BBInterceptor 时,出现了一个看起来很奇怪的编译器错误。

这是代码

template< class T>
class Singleton
{
protected:
    static T* ms_Singleton;
    Singleton()
    {
        if(!ms_Singleton)ms_Singleton = new T;
    }
public:
    static T& getSingleton( void ){assert( 0); return *ms_Singleton; }
};

struct InterceptorData
{
    unsigned int flag;

    InterceptorData():flag(0){}
};

template <class C, void (C::*TMethod)(const InterceptorData*)>
class InterceptorManager : public Singleton< InterceptorManager<C,TMethod> >
{

};

class AClass
{
public:
    virtual void Amethod(const InterceptorData* p_data = 0){};
};

class AAInterceptor : public InterceptorManager<AClass, &AClass::Amethod>
{
public:
    static AAInterceptor& getSingleton(void)
    {
        if (!ms_Singleton) new AAInterceptor();
        assert( ms_Singleton );  
        return ( *(static_cast< AAInterceptor*>(ms_Singleton)) );
    }
};

class BClass
{
public:
    virtual void Bmethod(const InterceptorData* p_data = 0){};
};

class BBInterceptor : public InterceptorManager<BClass, &BClass::Bmethod>
{
public:
    static BBInterceptor& getSingleton(void)
    {
        if (!ms_Singleton) new BBInterceptor();
        assert( ms_Singleton );  
        return ( *(static_cast< BBInterceptor*>(ms_Singleton)) );  //Here is the error of compilation
    }
};

int main(void)
{
    AAInterceptor a;
    BBInterceptor b;
    return 0;
}

使用 GCC (http://codepad.org/Bi6zbsmq) 可以正常编译,但不能使用 MSVC2008。

这是 Visual Studio 中的错误:

error:  " error C2440: 'static_cast' : cannot convert from 'InterceptorManager<C,TMethod> *' to 'BBInterceptor *' " 58
with
1>        [
           1>            C=BClass,
           1>            TMethod=void AClass::`vcall'{0}'(const InterceptorData *)
           1>        ]
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

好像编译器把不同的模板混在一起了,不是吗?

提前感谢您的帮助

【问题讨论】:

  • 我没有看到静态成员的定义。并不是说它会导致您发布的错误。或者,这可能是导致问题的原因。
  • if (!ms_Singleton) new BBInterceptor(); 缺少一个作业顺便说一句。
  • 我刚刚添加了 #include &lt;cassert&gt; 并且在 VS2010 中编译的一切都很好。
  • Nawaz & Mat:好的thanx,我编辑了我的帖子,并在基本构造函数中添加了赋值。但问题仍然存在。 OmarOthman:我在 VS2008 中尝试过#include (我的项目只有 2008 年),但它并没有成功...... :(

标签: c++ templates compiler-errors singleton functor


【解决方案1】:

此代码不会导致编译错误,只是将虚拟调用包装到非虚拟函数中并获取它的地址。

template<typename T>
class Singleton
{
protected:
  static T* ms_Singleton;
  Singleton()
  {
    if(!ms_Singleton)ms_Singleton = new T;
  }
public:
  static T& getSingleton( void ){assert(0); return *ms_Singleton; }
};

template<typename T>
T* Singleton<typename T>::ms_Singleton = 0;

struct InterceptorData
{
  unsigned int flag;
  InterceptorData():flag(0){}
};

template <typename C, void (C::*TMethod)(const InterceptorData*)>
class InterceptorManager : public Singleton< InterceptorManager<C,TMethod> >
{
};

class AClass
{
public:
  void Amethod(const InterceptorData* p_data = 0){AmethodImpl(p_data);};
  virtual void AmethodImpl(const InterceptorData* p_data = 0){};
};

class AAInterceptor : public InterceptorManager<AClass, &AClass::Amethod>
{
public:
  static AAInterceptor& getSingleton(void)
  {
    if (!ms_Singleton) new AAInterceptor();
    assert( ms_Singleton );  
    return ( *(static_cast< AAInterceptor*>(ms_Singleton)) );
  }
};

class BClass
{
public:
  void Bmethod(const InterceptorData* p_data = 0){BmethodImpl(p_data);};
  virtual void BmethodImpl(const InterceptorData* p_data = 0){};
};

class BBInterceptor : public InterceptorManager<BClass, &BClass::Bmethod>
{
public:
  static BBInterceptor& getSingleton(void)
  {
    if (!ms_Singleton) new BBInterceptor();
    assert( ms_Singleton );  
    return ( *(static_cast< BBInterceptor* >(ms_Singleton)) );  
  }
};

int main(void)
{
  AAInterceptor a;
  BBInterceptor b;
  return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-21
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2016-01-23
    相关资源
    最近更新 更多