c++ 创建具有不同初始化的模板化类的变体

pkwftd7m  于 2022-12-24  发布在  其他
关注(0)|答案(2)|浏览(122)

我正在创建多种不同类型的编码器,主要区别在于用于初始化类的数据结构不同。

struct tagTypeInfo {
        uint16_t start;
        uint16_t last;
        uint16_t count;
        std::string name;
        rdwrT rdwr;
};

template <typename T>
class encodedTag
{
public:
    encodedTag(vector<tagTypeInfo> tagInfo_) : tagInfo(tagInfo_)
    {
        int start = 0;
        for(auto & tag : tagInfo)
        {
            tag.start = start;
            tag.last = start + tag.count - 1;
            start = start + tag.count;
        }
    }

    uint16_t encode(uint16_t tag, T tagType)
    {
        assert(tag<tagInfo[tagType].count)
        return( tagInfo[tagType].start + tag );
    }
    std::tuple<uint16_t, T> decode(uint16_t encodedTag)
    {
        int type = 0;
        uint16_t tag;
        // simple linear search as there are only a few entries
        for (auto it = begin(tagInfo); it != end(tagInfo); it++)
        {
            if (encodedTag >= it->start && encodedTag < it->last )
            {
                // tag is in the range
                return {encodedTag - it->start , (T)type};
            }
            type++;
        }
        assert(false);    
        return {0,(T)0};
    }
    std::string getName(T tagType) {return(tagInfo[tagType].name);}
    rdwrT getRdwr(T tagType) {return(tagInfo[tagType].rdwr);}
private:
    std::vector<tagTypeInfo> tagInfo;
};

extern std::vector<tagTypeInfo> rdTag;
extern std::vector<tagTypeInfo> wrTag;

//using rdTagEncode = encodedTag<rdTagT>(rdTag) <-- error

cpp文件包含:

std::vector<tagTypeInfo> rdTag {
        {0, 0, NUM_HOSTRDTAG,        "HostRdTag",    RDWR_RD},
        {0, 0, NUM_SYSRDTAG,         "SysRdTag",     RDWR_RD},
        {0, 0, NUM_GCRDTAG,          "GCRdTag",      RDWR_RD}
    };

std::vector<tagTypeInfo> wrTag {
        {0, 0, NUM_HOSTWRTAG,        "HostWrTag",    RDWR_WR},
        {0, 0, NUM_SYSWRTAG,         "SysWrTag",     RDWR_WR},
        {0, 0, NUM_GCWRTAG,          "GCWrTag",      RDWR_WR}
    };

我的目标是能够在其他地方用rdTagEncode myEncode;声明一个编码器,但是我似乎找不到正确的语法来做这件事,有什么建议吗?

ffscu2ro

ffscu2ro1#

使用派生类是最好的解决方案。感谢建议@appleapple

class encodedRdTag : public encodedTag<rdTagTypeT>
{
    public:
    encodedRdTag() : encodedTag({
        {0, 0, NUM_HOSTRDTAG,        "HostRdTag",    RDWR_RD},
        {0, 0, NUM_SYSRDTAG,         "SysRdTag",     RDWR_RD},
        {0, 0, NUM_GCRDTAG,          "GCRdTag",      RDWR_RD}
    }) {};
};

class encodedWrTag : public encodedTag<wrTagTypeT>
{
    public:
    encodedWrTag() : encodedTag({
        {0, 0, NUM_HOSTRDTAG,        "HostRdTag",    RDWR_RD},
        {0, 0, NUM_SYSRDTAG,         "SysRdTag",     RDWR_RD},
        {0, 0, NUM_GCRDTAG,          "GCRdTag",      RDWR_RD}
    }) {};
};
lf5gs5x2

lf5gs5x22#

为了完整起见,这里是我在上面的注解中提到的“基于类型的分派”方法。
注意:这段代码在原始问题中不起作用,因为rdTagwrTag是相同的类型,因此独立于类模板T,但根据您自己的回答,这可能是实际发生的情况。

#include <vector>

struct tagTypeInfo{};

struct rdTagTypeT{};
struct wrTagTypeT{};

std::vector<tagTypeInfo> get_default_info(rdTagTypeT); // return wrTag
std::vector<tagTypeInfo> get_default_info(wrTagTypeT); // return wdTag

template <typename T>
struct encodedTag
{
    encodedTag():encodedTag(get_default_info(T{})){}
    encodedTag(std::vector<tagTypeInfo> tagInfo) : tagInfo(tagInfo){};
    std::vector<tagTypeInfo> tagInfo;
};

using encodedRdTag = encodedTag<rdTagTypeT>;
using encodedWrTag = encodedTag<wrTagTypeT>;

void foo(){
    encodedRdTag rd;
    encodedWrTag rw;
}

相关问题