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

C++ 在无显式模板专门化的多态类中存储函数指针

C++ 在无显式模板专门化的多态类中存储函数指针,c++,templates,polymorphism,C++,Templates,Polymorphism,我试图创建一个助手类来抽象调用函数指针。根据其他人的反馈,我使用一个多态类来实现这一点(如下所示)。模板还用于减少代码重复 typedef void(*PFNFOO1) (int); typedef void(*PFNFOO2) (double); typedef void(*PFNBAR1) (long); typedef void(*PFNBAR2) (float); typedef struct FOO_TABLE { PFNFOO1 pfnFoo1; PFNFOO2 p

我试图创建一个助手类来抽象调用函数指针。根据其他人的反馈,我使用一个多态类来实现这一点(如下所示)。模板还用于减少代码重复

typedef void(*PFNFOO1) (int);
typedef void(*PFNFOO2) (double);
typedef void(*PFNBAR1) (long);
typedef void(*PFNBAR2) (float);

typedef struct FOO_TABLE
{
    PFNFOO1 pfnFoo1;
    PFNFOO2 pfnFoo2;
} FOO_TABLE;

typedef struct BAR_TABLE
{
    PFNBAR1 pfnBar1;
    PFNBAR2 pfnBar2;
} BAR_TABLE;

enum TABLE_TYPE
{
    TYPE_FOO = 0,
    TYPE_BAR = 1,
};

template <typename T>
class FooBarImpl : public FooBarBase
{
public:  
    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
    void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }
    void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
    void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }

    T* m_FooBarTable;
};

class FooBarBase
{
public:
    static FooBarBase* CreateFooBar(TABLE_TYPE tableType)
    {
        switch(tableType)
        {               
            case (TYPE_FOO) :
            {
                return new FooBarImpl<FOO_TABLE>();
            }
            break;

            case (TYPE_BAR) :
            {
                return new FooBarImpl<BAR_TABLE>();
            }
            break;
        }                

    }

    virtual void* GetpfnFoo1() = 0;
    virtual void* GetpfnFoo2() = 0;
    virtual void* GetpfnBar1() = 0;
    virtual void* GetpfnBar2() = 0;
};

int _tmain(int argc, _TCHAR* argv[])
{
    {
        FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
        // Initialize Foo table
        auto p = reinterpret_cast<PFNFOO1>(pFooBar->GetpfnFoo1());
        int parameter = 1;
        p(parameter);
    }

    {
        FooBarBase *pFooBar = FooBarBase::CreateFooBar(TYPE_FOO);
        // Initialize Bar table
        auto p = reinterpret_cast<PFNBAR2>(pFooBar->GetpfnBar2());
        float parameter = 1.0f;
        p(parameter);
    }   

    return 0;
}
typedef void(*PFNFOO1)(int);
类型定义无效(*PFNFOO2)(双);
类型定义无效(*PFNBAR1)(长);
类型定义无效(*PFNBAR2)(浮动);
typedef struct FOO_表
{
PFNFOO1-PFNFOO1;
PFNFOO2-PFNFOO2;
}富奥表;
typedef结构条形图表格
{
PFNBAR1 PFNBAR1;
PFNBAR2 PFNBAR2;
}吧台;
枚举表类型
{
类型_FOO=0,
类型_BAR=1,
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(m_FooBarTable+funcOffset);
}
void*GetpfnFoo1(){return GetFunc(offsetof(T,pfnFoo1));}
void*GetpfnFoo2(){return GetFunc(offsetof(T,pfnFoo2));}
void*GetpfnBar1(){return GetFunc(offsetof(T,pfnBar1));}
void*GetpfnBar2(){return GetFunc(offsetof(T,pfnBar2));}
T*m_foobatable;
};
食品类
{
公众:
静态foobase*CreateFooBar(表类型tableType)
{
开关(台式)
{               
案例(类型_-FOO):
{
返回新的FooBarImpl();
}
打破
箱子(U型钢):
{
返回新的FooBarImpl();
}
打破
}                
}
虚拟void*GetpfnFoo1()=0;
虚拟void*GetpfnFoo2()=0;
虚空*GetpfnBar1()=0;
虚空*GetpfnBar2()=0;
};
int _tmain(int argc,_TCHAR*argv[]
{
{
FooBarBase*pFooBar=FooBarBase::CreateFooBar(TYPE_FOO);
//初始化Foo表
自动p=重新解释(pFooBar->GetpfnFoo1());
int参数=1;
p(参数);
}
{
FooBarBase*pFooBar=FooBarBase::CreateFooBar(TYPE_FOO);
//初始化条表
自动p=重新解释(pFooBar->GetpfnBar2());
浮动参数=1.0f;
p(参数);
}   
返回0;
}
这目前给我带来了复杂的错误“C2039:‘pfnBar1’:不是‘FOO_TABLE’的成员”,这是有意义的,因为其中一个隐式模板专门化将尝试执行“offsetof(FOO_TABLE,pfnBar1)”,这是不允许的。我有两个问题。首先,我想知道解决这个错误的最佳方法是什么。我想我可以通过为FooBarImpl和FooBarImpl提供显式的模板专门化来解决这个问题,但是我想避免这样做,因为这意味着如果我以后要添加一个新的表类型,我必须添加另一个专门化。此外,它还增加了代码重复。因此,如果有一种方法可以在没有显式模板专门化的情况下解决此问题,请让m知道

对于第二个问题,如果无法避免显式模板专门化,我也尝试了以下方法:

class FooBarBase;

template <typename T>
class FooBarImpl : public FooBarBase
{
};

template <>
class FooBarImpl<FOO_TABLE> : public FooBarBase
{
public:
    typedef FOO_TABLE T;

    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnFoo1() { return GetFunc(offsetof(T, pfnFoo1)); }
    void* GetpfnFoo2() { return GetFunc(offsetof(T, pfnFoo2)); }

    T* m_FooBarTable;
};

template<>
class FooBarImpl<BAR_TABLE> : public FooBarBase
{
public:
    typedef BAR_TABLE T;

    // GetFunc is created to centralize needed validation before function is invoked
    void* GetFunc(size_t funcOffset)
    {
        // do some validation
        return reinterpret_cast<void*>(m_FooBarTable + funcOffset);
    }

    void* GetpfnBar1() { return GetFunc(offsetof(T, pfnBar1)); }
    void* GetpfnBar2() { return GetFunc(offsetof(T, pfnBar2)); }

    T* m_FooBarTable;
};
class-foobase;
样板
FooBarImpl类:公共Foobaribase
{
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
类型def FOO_表T;
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(m_FooBarTable+funcOffset);
}
void*GetpfnFoo1(){return GetFunc(offsetof(T,pfnFoo1));}
void*GetpfnFoo2(){return GetFunc(offsetof(T,pfnFoo2));}
T*m_foobatable;
};
样板
FooBarImpl类:公共Foobaribase
{
公众:
typedef BAR_表T;
//创建GetFunc是为了在调用函数之前集中所需的验证
void*GetFunc(大小函数偏移量)
{
//做一些验证
返回reinterpret_cast(m_FooBarTable+funcOffset);
}
void*GetpfnBar1(){return GetFunc(offsetof(T,pfnBar1));}
void*GetpfnBar2(){return GetFunc(offsetof(T,pfnBar2));}
T*m_foobatable;
};
但出于某种原因,我不断收到这个错误“error C2504:'FooBarBase':基类未定义”,即使在我专门化模板之前它工作正常


如果有人对这两个问题有想法,我将非常感谢您的反馈。谢谢。

你到底想用这个实现什么?“助手类到抽象调用函数指针”-你没有抽象任何东西。。。您的客户端使用点假定特定的运行时类型和重新解释\u casts,以便可以恢复特定的成员。做
dynamic\u cast
所允许的事情实际上是一种不安全的尝试,但即使这样做也毫无意义,因为没有统一的基类行为来证明继承的合理性。为什么不创建一个包含FOO_TABLE和BAR_TABLE的并集以及一个int的结构来告诉您哪个是有意义的呢?你的额外代码除了模糊处理之外什么都买不到。这样做的主要目的是在创建函数表时,我们可以在调用函数指针时强制执行严格验证和松散验证。很难用一个小的自包含示例来说明这一点,所以请耐心听我说。此外,这些函数指针被多次调用,这样就省去了一堆重复的switch语句来确定应该从哪个表调用函数指针。而这不能用一个简单的wrapperfunction来完成吗?我这样问是因为我试图理解,在不破坏用例的情况下,代码的哪一部分是可以更改的。