关于虚函数的模板化的问题

时间:2010-03-25 20:25:34

标签: c++ templates

我知道你无法模仿虚拟功能,我确实理解它背后的概念。但是我仍然需要一种方法来克服我遇到的一些错误。我可以让我的东西工作,但它看起来不对我。

我有一个名为System的课程:

#include "Vector.h"
class System
{
    virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos =  0)      const  = 0;  
};

class UnresolvedSystem : public System
{
    virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const
    {
      //do something 
    }  
};

Vector.h

tenplate<typename T>
class Vector
{
  //some functions
};

现在我想在VectorToLocal中对system.h进行模板化以仅采用Vector<T>,但我不能这样做,因为它是一个虚函数。我想要一个解决方案。我知道我可以VectorToLocalVector<float>Vector<double>等作为参数,但我不想这样做。

6 个答案:

答案 0 :(得分:2)

会员功能模板不能是虚拟的。没有两种方式。

但虚拟成员函数可以采用恰好使用模板的完全定义的类型:

class System
{
public:
    virtual void DoIt(vector<int>* v);
};


int main()
{
    vector<int> v;
    System s;
    s.DoIt(&v);
    return 0;
}

顺便问一下,为什么要实现自己的矢量类?

答案 1 :(得分:1)

任何消除虚拟功能的常用方法(如CRTP)也会有所帮助。

答案 2 :(得分:0)

我不知道你想用你的向量做什么,但有时候可以让模板函数调用一个实现实际行为的虚函数。在这种情况下,您将在您的超类中实现模板版本,并使其在那里调用非模板纯虚拟,以执行您想要执行的任何操作。这通常只有在对type-parameter:

进行限制时才有效
#include "Vector.h"
class System
{
    virtual void print( const std::string & ) const = 0;
    template<class T>
    void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos =  0) const {
        print( T.GetName() );
    }
};

class UnresolvedSystem : public System
{
    virtual void print( const std::string & Name ) const {
        std::cout << name << std::endl;
    }  
};

在这种情况下,我假设T有一个成员函数GetName

答案 3 :(得分:0)

如果定义C ++模板函数,则会为模板参数类型的每个组合创建一个新的函数实现。因此源中的单个函数可以是机器代码中的一个或多个函数。这有助于使他们快速。

现在,编译器根据调用方式确定要生成函数的哪个版本。如果int永远不是类型参数,则不会禁止编译器生成实现。现在,如果您进行虚拟调用,则很难找到它的使用方式,并且可能是在编译使用模板函数的函数时函数的定义不在头文件中。如果没有函数的源代码,编译器就无法创建编译函数。

当C ++允许虚拟模板功能时,您还会遇到一些其他不切实际的问题。就像通常实现虚拟功能一样。

这可能是C ++不允许它的原因。您可能认为自己需要它,但可能有另一种方式,我相信如果您向我们提供有关此代码段背后的要求的更多细节,我们相信人们会帮助您找到。

答案 4 :(得分:0)

您有多种选择,全部取决于您要做的事情。

如果T以某种方式固有System(例如,如果System具有T类型的成员变量),则可以使整个类模板化:< / p>

template< typename T >
class System
{
    virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos =  0)      const  = 0;  
};

template< typename T >
class UnresolvedSystem : public System<T>
{
    virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const
    {
      //do something 
    }  
};

如果T的上下文仅为VectorToLocal的本地上下文,那么更好的设计决策是将该函数计算在该类之外:

template< typename T >
void VectorToLocal( System& s, Vector<T>& global_dir, ... )
{
   // use s's public interface to make changes to the object
}

您能否提供有关VectorToLocal的目的的详细信息?

答案 5 :(得分:0)

如果您想要提供单个实施点,则可以将调用转发给模板

struct base {
   virtual void f( int );
   virtual void f( double );
};

struct derived : base {
   virtual void f( int x ) { f_tmpl(x); }
   virtual void f( double x ) { f_tmpl(x); }

   template <typename T>
   void f_tmpl( T x ) { // ... }
};

我敢打赌,使用类型列表可以实际生成虚函数,但这可能会使代码复杂化。