当前位置: 首页 > 知识库问答 >
问题:

通过枚举查找返回元组值(不同类型)的模板函数

孔建柏
2023-03-14
#include <iostream>
#include <string>
#include <tuple>

// IDs
enum class ID : size_t
{
    AAA, // 0
    BBB, // 1
    CCC, // 2
    DDD  // 3
};

// default values for each ID
const auto defaultValsForIDs = std::make_tuple(
        int(1),             // 0
        std::string("bbb"), // 1 
        double(3.5),        // 2
        int(-5)             // 3
);


//------------------------------------------------------
// HERE IS WHERE IT GETS MESSY:
//------------------------------------------------------
// default values for each deviceID
template<typename EnumT>
using underlayingEnumT = typename std::underlying_type<EnumT>::type;

template<typename EnumT>
constexpr underlayingEnumT<EnumT> to_underlying(EnumT e) 
{
    return static_cast<underlayingEnumT<EnumT>>(e);
}

template<typename EnumT>
auto getDefaultValue(const EnumT e) 
-> decltype(std::get<to_underlying<EnumT>(e)>(defaultValsForIDs)) // <- THIS WON'T WORK
{
    return std::get<to_underlying<EnumT>(e)>(defaultValsForIDs);
}


//------------------------------------------------------
// THIS DOES NOT COMPILE AS WELL
//------------------------------------------------------
template<>
auto getDefaultValue(const size_t xx) 
-> decltype(std::get<xx>(defaultValsForIDs)) // <- THIS WON'T WORK
{
    return std::get<xx>(defaultValsForIDs);
}

int main(int , char** )
{
    std::cout << getDefaultValue(ID::AAA) << std::endl;

    return 0;
}

已更改:

template<typename EnumT, EnumT e>
auto getDefaultValue() 
-> decltype(std::get<to_underlying<EnumT>(e)>(defaultValsForIDs))
{
    return std::get<to_underlying<EnumT>(e)>(defaultValsForIDs);
}

并为ID添加了实例:

template<ID id>
auto getDefaultValForID() 
-> decltype(getDefaultValue<ID, id>())
{
    return getDefaultValue<ID,id>();
}

然后:

int main()
{
    std::cout << getDefaultValForID<ID::BBB>() << std::endl;

    return 0;
}

共有1个答案

淳于恺
2023-03-14

函数参数不是常量表达式,因此不能用作非类型模板参数。相反,您需要将其提升到模板参数列表:

template <std::size_t xx>
auto getDefaultValue() 
    -> decltype(std::get<xx>(defaultValsForIDs))
{
    return std::get<xx>(defaultValsForIDs);
}

template <typename EnumT, EnumT e>
auto getDefaultValue() 
    -> decltype(std::get<to_underlying<EnumT>(e)>(defaultValsForIDs))
{
    return std::get<to_underlying<EnumT>(e)>(defaultValsForIDs);
}

然后像这样使用它:

getDefaultValue<ID, ID::AAA>()

getDefaultValue<0>() 
 类似资料:
  • 枚举具有名为'hash value'的属性,该属性是枚举内的索引。

  • 我的模式如下 我正在尝试编写一个方法来检查代码并返回相应的枚举。 event.getStatusCode的有效值是:A,T,U。现在我需要检查这些代码并根据代码返回枚举。我尝试了上面的方法,但它给我代码=["A"]的错误。下面是错误状态。 我该怎么解决这个问题?我是java新手。非常感谢您的帮助,谢谢

  • 我正在使用一种通信标准(我无法控制),该标准定义要在各种数据包中发送/接收的数据项。 每个项目都由自定义类型和类型相关信息定义。这些项目很少会改变。我希望能够将项目构造函数的范围限制在一个地方,并将那里的所有项目定义为(类似于枚举)。 目前,我有一个用于类型的枚举和一个用于项的类。 这已经变得难以管理,我正在寻找更好的模式/结构。 我可以有一个抽象的Item类,以及每种类型的子类。使用此设置,我不

  • 问题内容: 也许这是一个愚蠢的问题,但是有没有办法找到所有返回特定类型的函数(在标准库或GOPATH中)? 例如,有许多函数使用io.Writer作为参数。现在,我想知道如何创建io.Writer,并且有很多方法可以做到这一点。但是,如何能轻松地找到所有方法而又无需猜测软件包并仔细查看所有方法以找到返回io.Writer(或我追随的其他任何类型)的方法? 编辑: 我应该扩展我的问题,以查找实现特定

  • 我遇到了以下代码,其行为是由所有GCC、Clang和MSVC商定的: 现场演示:https://godbolt.org/z/hK6xhesKM 在全局命名空间中声明,并带有推断的返回类型<代码>S 我所期望的是,当用〈code〉U=double〈code〉实例化〈code〉S〈code〉时,它对〈code〉foo()〈code〉的定义被放入全局命名空间,并且〈code〉U〈code〉被替换,因为友