Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 关于虚拟函数模板化的问题_C++_Templates - Fatal编程技术网

C++ 关于虚拟函数模板化的问题

C++ 关于虚拟函数模板化的问题,c++,templates,C++,Templates,我知道你不能模板化一个虚拟函数,我理解它背后的概念。但我仍然需要一种方法来克服我遇到的一些错误。我能让我的东西正常工作,但我觉得不太对劲 我有一门叫做系统的课: #include "Vector.h" class System { virtual void VectorToLocal(Vector<T>& global_dir,const Vector<T>* global_pos = 0) const = 0; }; class Un

我知道你不能模板化一个虚拟函数,我理解它背后的概念。但我仍然需要一种方法来克服我遇到的一些错误。我能让我的东西正常工作,但我觉得不太对劲

我有一门叫做
系统的课

#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 
    }  
};

现在我想在
system.h
中模板化
vectorolal
,只取
Vector
,但我不能这样做,因为它是一个虚拟函数。我想找个工作。我知道我可以使用
vectorol
Vector
Vector
等作为参数,但我不想这样做。

成员函数模板不能是虚拟的。没有两条路可走

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

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


int main()
{
    vector<int> v;
    System s;
    s.DoIt(&v);
    return 0;
}
类系统
{
公众:
虚空DoIt(向量*v);
};
int main()
{
向量v;
系统s;
s、 DoIt&v;
返回0;
}

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

我不知道您想对vector做什么,但有时可以让模板函数调用实现实际行为的虚拟函数。在这种情况下,您将在超类中实现模板版本,并使其调用一个非模板纯虚拟类,该类可以执行您想要执行的任何操作。这通常仅适用于对类型参数施加限制的情况:

#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;
    }  
};
#包括“Vector.h”
阶级制度
{
虚拟空打印(const std::string&)const=0;
模板
void vectorolal(向量和全局_dir,常量向量*全局_pos=0)常量{
打印(T.GetName());
}
};
类UnsolvedSystem:公共系统
{
虚拟空打印(常量标准::字符串和名称)常量{

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

现在,编译器通过调用函数的方式来确定生成函数的哪个版本。如果
int
从来都不是类型参数,则不支持编译器生成实现。现在,如果进行虚拟调用,则很难找到如何使用该函数,并且函数的定义可能不在标头中编译使用模板函数的函数时使用的文件。如果没有该函数的源代码,编译器将无法创建已编译的函数

当C++允许虚拟模板功能时,还有一些其他的不切实际的地方。比如虚拟函数通常是如何实现的。
<> p>这可能是C++不允许的原因。你可能认为你需要它,但可能还有另外一种方法,我相信人们会帮助你找到这个代码片段背后的要求的更详细的说明。

你有几个选项,都取决于你想做什么。 如果
T
某种程度上是
System
固有的(例如,如果
System
具有类型为
T
的成员变量),则可以在其上模板化整个类:

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 
    }  
};

您能否提供有关
vectorolal
用途的更多详细信息?

如果您希望提供单个实现点,则可以将调用转发到模板

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 ) { // ... }
};
struct base{
虚空f(int);
虚空f(双);
};
派生结构:基{
虚空f(int x){f_tmpl(x);}
虚空f(double x){f_tmpl(x);}
模板
void f_tmpl(tx){/…}
};

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

任何消除虚拟函数的常用方法,如CRTP,也会有所帮助。

对类型
T
有任何限制吗?T可以是浮点、双精度、复杂或复杂的。我知道这就是我正在做的现在,我通过指定为vector、vector等显式调用。我想知道是否有解决方法。我使用自己的vector类,因为它与std::vector完全不同,这是一个计算点积、叉积、幅值等的特殊类。感谢您的即时回复。另一种方法是什么嗯,如果我想调用具有模板化参数的虚拟函数呢?这可能是问题所在吗?很抱歉,正如一些人已经指出的那样,没有办法使模板函数虚拟化。但是如果您更好地解释您试图实现的目标,我们可能会向您展示另一种解决方案。实际上,这就是我实现的到目前为止,它并不复杂,但看起来像一个。我无法模板化系统类,因为它从名为Entity的类继承而来,从名为Record的类继承而来。很抱歉,我忘了提及我的问题。因此VectorLocal使用Vector做了一些数学运算,最后在类系统中设置了一个MemberVariable。示例system class包含名为RMat4 _mat的成员变量,它实际上是一个4x4矩阵。我建议使用第二种方法。将vectorolal()设为非成员模板函数,将setMat(const RMat4&newMat)函数添加到系统中,并让vectorolal()调用它。CRTP代表奇怪的重复模板模式:
template< typename T >
void VectorToLocal( System& s, Vector<T>& global_dir, ... )
{
   // use s's public interface to make changes to the object
}
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 ) { // ... }
};