Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.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_C++11_Enums - Fatal编程技术网

C++ 将字符串和枚举映射到模板化类型

C++ 将字符串和枚举映射到模板化类型,c++,templates,c++11,enums,C++,Templates,C++11,Enums,我的函数foo接受两个参数——一个字符串str和一个强类型enum ENUM1。它应该实例化一个类模板,其模板参数依赖于str和ENUM1。如何在不使用以下多个if..then..else语句的情况下实现这一点 void foo(std::string str, ENUM1 enumVal) { if (str == "str1" && enumVAL == ENUM1::VAL1) ExampleClass<STR1TYPE, VAL1TYP

我的函数foo接受两个参数——一个字符串str和一个强类型enum ENUM1。它应该实例化一个类模板,其模板参数依赖于str和ENUM1。如何在不使用以下多个if..then..else语句的情况下实现这一点

void foo(std::string str, ENUM1 enumVal) {
    if (str == "str1" && enumVAL == ENUM1::VAL1)
           ExampleClass<STR1TYPE, VAL1TYPE> instance;
    else if (str == "str1" && enumVAL == ENUM1::VAL2)
           ExampleClass<STR1TYPE, VAL2TYPE> instance;
    else if (str == "str2" && enumVAL == ENUM1::VAL1)
           ExampleClass<STR2TYPE, VAL1TYPE> instance;
    ...
}
void foo(std::string str,ENUM1 enumVal){ if(str==“str1”&&enumVAL==ENUM1::VAL1) 示例类实例; else if(str==“str1”&&enumVAL==ENUM1::VAL2) 示例类实例; else if(str==“str2”&&enumVAL==ENUM1::VAL1) 示例类实例; ... } 我无法更改ExampleClass的设计方式,也无法更改传入的参数类型。我讨厌if-then-else对于两个参数值的所有排列

我想保留一个
std::unordered_map
,但这意味着需要占用内存来保存代码的可读性


有没有更好的方法可以做到这一点?

好吧,这是一个模板和类型特征的小例子

首先-单箱的功能对您来说非常有用:

template <typename StrType, typename EnumType>
void fooSingleCase()
{
    std::cout << "In: " << __PRETTY_FUNCTION__ << "\n"; 
    ExampleClass<StrType, EnumType> instance;
    // ...
}
还有一些例子:

template <>
const std::string StrTraits<STR1TYPE>::pattern = "str1";
template <>
const std::string StrTraits<STR2TYPE>::pattern = "str2";

template <>
const ENUM1 ENUM1Traits<VAL1TYPE>::pattern = ENUM1::VAL1;
template <>
const ENUM1 ENUM1Traits<VAL2TYPE>::pattern = ENUM1::VAL2;
template <>
const ENUM1 ENUM1Traits<VAL3TYPE>::pattern = ENUM1::VAL3;
模板
const std::string StrTraits::pattern=“str1”;
模板
const std::string StrTraits::pattern=“str2”;
模板
常量ENUM1 ENUM1Traits::pattern=ENUM1::VAL1;
模板
常量ENUM1 ENUM1Traits::pattern=ENUM1::VAL2;
模板
常量ENUM1 ENUM1Traits::pattern=ENUM1::VAL3;

所以-我们几乎完成了。我们现在需要让模板变魔术:

首先-假设您已经获得EnumType-只需选择strType-因此-开始使用traits:

template <typename EnumType>
void fooFixedEnumCase(std::string strVal)
{
    std::cout << strVal << " not found!\n";
}

template <typename EnumType, typename Str1Type, typename ...StrType>
void fooFixedEnumCase(std::string strVal)
{
    if (StrTraits<Str1Type>::pattern == strVal)
        fooSingleCase<EnumType, Str1Type>();
    else
        fooFixedEnumCase<EnumType, StrType...>(strVal);
}
模板
void fooFixedEnumCase(std::string strVal)
{

std::cout切换到
unordered_map
只是用堆内存换取代码大小-您当前的硬编码方法会导致额外的可执行文件大小。其中一个可能会稍微小一些,但除非您处于内存严重受限的环境中,否则这种差异不应该让您太担心。实际上,内存占用率所以目前,我已经使用if-then-elses实现了,并且正在寻找一个更智能、更可读的实现。
template <>
const std::string StrTraits<STR1TYPE>::pattern = "str1";
template <>
const std::string StrTraits<STR2TYPE>::pattern = "str2";

template <>
const ENUM1 ENUM1Traits<VAL1TYPE>::pattern = ENUM1::VAL1;
template <>
const ENUM1 ENUM1Traits<VAL2TYPE>::pattern = ENUM1::VAL2;
template <>
const ENUM1 ENUM1Traits<VAL3TYPE>::pattern = ENUM1::VAL3;
template <typename EnumType>
void fooFixedEnumCase(std::string strVal)
{
    std::cout << strVal << " not found!\n";
}

template <typename EnumType, typename Str1Type, typename ...StrType>
void fooFixedEnumCase(std::string strVal)
{
    if (StrTraits<Str1Type>::pattern == strVal)
        fooSingleCase<EnumType, Str1Type>();
    else
        fooFixedEnumCase<EnumType, StrType...>(strVal);
}
template <typename ...EnumType>
struct Enum1Switch;

template <typename EnumType1, typename ...EnumType>
struct Enum1Switch<EnumType1, EnumType...>
{
    template <typename ...StrType>
    static void strSwitch(std::string str, ENUM1 enumVal)
    {
        if (ENUM1Traits<EnumType1>::pattern == enumVal)
            fooFixedEnumCase<EnumType1, StrType...>(str);
        else
            Enum1Switch<EnumType...>::template strSwitch<StrType...>(str, enumVal);
    }
};

template <>
struct Enum1Switch<>
{
    template <typename ...StrType>
    static void strSwitch(std::string str, ENUM1 enumVal)
    {
        std::cout << static_cast<int>(enumVal) << " not found!\n";
    }
};
void foo(std::string str, ENUM1 enumVal) {

    Enum1Switch<VAL1TYPE, VAL2TYPE, VAL3TYPE>
        ::strSwitch<STR1TYPE, STR2TYPE>(str, enumVal);
}
template <>
const std::string StrTraits<STRTYPENEW>::pattern = "newstr";
template <>
const ENUM1 ENUM1Traits<VALTYPENEW>::pattern = ENUM1::NEW_VAL;
void foo(std::string str, ENUM1 enumVal) {

    Enum1Switch<VAL1TYPE, VAL2TYPE, VAL3TYPE, VALTYPENEW>
    //                                      ^^^^^^^^^^^^
        ::strSwitch<STR1TYPE, STR2TYPE, STRTYPENEW>(str, enumVal);
    //                                ^^^^^^^^^^^^  
}