c++ - 通过 ENUM 查找返回元组值(不同类型)的模板函数

标签 c++ templates c++11 tuples return-type-deduction

下面的代码产生

"error: invalid operands of types '' and 'const size_t {aka const long unsigned int}' to binary 'operator<'" (gcc-4.9.1)

我只想要一个查找不同类型默认值的函数。这应该有效吗?

#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;
}

我是不是在某处遗漏了一个模板? 看 Where and why do I have to put the "template" and "typename" keywords? 或者 Compile error: unresolved overloaded function type

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
按照 Piotr 的建议进行编辑:

改变了:

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;
}

很有魅力。

最佳答案

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

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>() 

DEMO

关于c++ - 通过 ENUM 查找返回元组值(不同类型)的模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32885112/

相关文章:

c++ - 将数组中的所有元素与另一个数组进行比较

c++ - g++ 和 clang++ 都存在模板函数参数包扩展问题?

c++ - 从共享库公开 C++ 模板方法

linux - 错位指针以节省空间 : How to do this cleanly without UB?

c++ - stringstream 读取失败是不确定的吗?

c++ - QAbstractProxyModel 不更新 dataChanged() 信号

c++ - 我如何遍历 malloc? (开放式简历)

c++ - 在套接字 C++ 中选择不起作用

C++:以下代码有什么问题吗?

c++ - std::function operator() 和 std::forward 发生了什么?