Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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

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_Derived Class - Fatal编程技术网

C++ 通过基类指针调用右模板函数

C++ 通过基类指针调用右模板函数,c++,templates,derived-class,C++,Templates,Derived Class,我想我已经接近解决方案了,但我错过了最后一步。 我想调用一个模板成员函数,其中我只有一个指针 对于基类,类型已经预定义,因此不应 取决于实际参数类型 这就是我所拥有的: template <typename T> class TTemplateTest; class CTemplateTest { public : CTemplateTest(){}; template <typename T> double Process(T atValue)

我想我已经接近解决方案了,但我错过了最后一步。 我想调用一个模板成员函数,其中我只有一个指针 对于基类,类型已经预定义,因此不应 取决于实际参数类型

这就是我所拥有的:

template <typename T> class TTemplateTest;

class CTemplateTest
{
public :
    CTemplateTest(){};
    template <typename T> double Process(T atValue)
    {
        return static_cast<TTemplateTest<T>* >(this)->Process(atValue);
    }
};
//------------------------------
template <class T>
class TTemplateTest:public CTemplateTest
{
    public :
        TTemplateTest() : CTemplateTest(){};
        virtual double Process(T atNewValue) {return atNewValue;};
};
//------------------------------
template <class T>
class TTemplateTestInt:public TTemplateTest<T>
{
public :
    TTemplateTestInt(){};
    virtual double Process(T atNewValue);
};
//------------------------------
template <class T> double TTemplateTestInt<T>::Process(T atNewValue)
{
    return atNewValue;
}

CTemplateTest* pTTest = new TTemplateTestInt<int>();

// application code
double d = 5.5;
double r;
r = pTTest->Process(d);
在本例中,我想将参数处理为整数, 不管论点是什么类型的。它调用正确的函数 但是该值是垃圾,因为double被解释为integer 而不是被转换

我看了其他的问题和其他的网站,但不能 找到匹配项或解决方案,例如。

解决方案可能是CRTP,但我不知道如何解决 使用它。应用程序代码应保持如下状态: 类定义可以更改。此代码的原因是 它是在运行时从一些xml生成和使用的 配置文件。因此,目前还不知道这种类型 函数调用

如果我可以使用定义的类型,可能会有所帮助,例如:

template <typename T> double Process(T atValue)
{
    return static_cast<TTemplateTest<T>* >(this)->Process((this::type)atValue);
}
或者使用double阻止自动创建函数 因此,参数被转换为整数,就像它在 非模板函数

谢谢你的帮助

编辑:下一个解决方案

这看起来有效吗?它不需要强制转换,我们只需要模板的几个不同的基本类型,这样就不会有很多重定向器函数。如果没有typeinfo之类的东西,它仍然应该是高效的。 我也张贴它,以防其他人有类似的问题

class CTemplateTest
{
public :
    CTemplateTest(){};
    virtual inline double Process(double adValue)=0;
    virtual inline double Process(int aiValue)=0;
};
//------------------------------
template <class T>
class TTemplateTest:public CTemplateTest
{
    public :
        TTemplateTest() : CTemplateTest(){};
        virtual inline double Process(double adValue) {
            return ProcessImp((T)adValue);
        }
        virtual inline double Process(int aiValue) {
            return ProcessImpl((T)aiValue);
        }
        virtual double ProcessImpl(T atNewValue)=0;
};
//------------------------------
template <class T>
class CTemplateTestInt:public TTemplateTest<T>
{
public :
    CTemplateTestInt(){};
    virtual double ProcessImpl(T atNewValue) {return atNewValue;};
};
然后,这就给出了所需的结果

CTemplateTest* pTTest = new TTemplateTestInt<int>();

// application code
double d = 5.5;
double r;
r = pTTest->Process(d);
// -> r = 5

谢谢

您的代码在命名和逻辑方面看起来相当混乱。我不知道您想做什么,但我可以解释为什么您的代码会导致奇怪的行为,这也表明您的代码中存在一些基本的设计缺陷

为了简化,您的代码类似于以下内容:

class A {};

class B : public A {};

class C : public A {};

int main () {
    A *a_ptr = new B {};
    C *c_ptr = static_cast<C*>(a_ptr);
}
将通过模板参数推断而不是从任何预定义类型获得类型T。因此,pTTest->Processd将推断类型T为double,在该函数中,static_将this指针转换为不相关的指针TTemplateTest*。但这个指针实际上是一个TTemplateTest*,这两个类之间没有任何关系,除非它们都是从ctTemplateTest派生的。所以这只是一个简化的例子

我不知道如何修复此代码…

一些观察结果:

1基类没有虚函数,但派生类都有唯一的、不相关的虚函数。它们不会覆盖任何内容,所以虚拟化是毫无意义的

2基类不知道派生类型是用什么类型实例化的。调用ctTemplateTest::Process时,T是为函数调用推导的参数,与用于派生类型的T无关。您只是将对象强制转换为使用提供的类型实例化的模板,而忽略了对象实际的类型。这就是垃圾的原因;这是未定义的行为

3没有模板虚拟函数这样的东西。一个或另一个;你挑吧。这基本上就是我认为你想要模拟的。您希望同一个函数接受任何类型的参数,并将其作为该类型传递给派生类型,而派生类型知道如何以自己的模板化方式处理它。我不确定是否有一个令人满意的方法来完成这项工作


一个想法是预先确定一组固定的类型,您将接受并单独处理它们,每个支持的类型一个虚拟函数。您可以使用模板参数列表使其更加灵活,并使用编译器生成函数,但我还没有完全考虑过这种方法

在你的情况下,你的演员阵容将导致UB。不确定你想做什么,什么不应该改变…应用程序代码。应该可以有一个基类指针,并使用各种参数类型调用它,但它应该始终调用预定义的函数。cast正是我想到的,我对更好的解决方案持开放态度。因此,在函数调用时,类型并不真正为人所知。C++使用错误的静态类型,因此在编译时应该知道类型:.f.cEnDESe关于UB的细节:函数中的两个模板类型和类是独立的,模板函数中发生的情况是,除了继承从Progress5.5推导出的相同基类TTemplateTestInt之外,您将TTemplateTestInt类型的对象强制转换为完全不相关的对象类型这就是古怪行为的来源……是的,我已经发现这不起作用。如果类型取自实例/指针而不是参数,如何调用模板函数?还是根本不可能?正如我所说的,应用程序代码是理想的用例,如果有办法达到这个目标,整个层次结构和模板都可以更改。@F.Cenedese如果没有运行时类型信息,这是不可能的。因为你想要你的函数支持
t int和double,即使没有模板,这两个签名也必须存在于基类中。编译器将选择仅由参数调用的一个。您可以在单个基类中记录该类型的一些运行时信息,并自己进行动态调度。是否有可能从模板类中获取该类型,以便在调用函数之前将参数强制转换为该类型?正如我所知,没有直接的方法。但是如果只涉及几个类,那么自己写就不难了。标题可能会有所帮助。
template <typename T> double Process(T atValue)
{
    return static_cast<TTemplateTest<T>* >(this)->Process(atValue);
}