c++ - std::get 使用枚举类作为模板参数

标签 c++ get c++11 tuples enum-class

我正在使用 std::tuple 并定义了一个枚举类以某种方式“命名”元组的每个字段,而忘记了它们的实际索引。

所以不要这样做:

std::tuple<A,B> tup;
/* ... */
std::get<0>(tup) = bleh; // was it 0, or 1?

我这样做了:

enum class Something {
     MY_INDEX_NAME = 0,
     OTHER_INDEX_NAME
};

std::tuple<A,B> tup;
/* ... */
std::get<Something::MY_INDEX_NAME> = 0; // I don't mind the actual index...

问题是,因为这个是用gcc 4.5.2编译的,我现在安装的是4.6.1版本,我的项目编译失败。此代码段重现了错误:

#include <tuple>
#include <iostream>

enum class Bad {
    BAD = 0
};

enum Good {
    GOOD = 0
};

int main() {
    std::tuple<int, int> tup(1, 10);
    std::cout << std::get<0>(tup) << std::endl;
    std::cout << std::get<GOOD>(tup) << std::endl; // It's OK
    std::cout << std::get<Bad::BAD>(tup) << std::endl; // NOT!
}

该错误基本上表明没有与我对 std::get 的调用相匹配的重载:

test.cpp: In function ‘int main()’:
test.cpp:16:40: error: no matching function for call to ‘get(std::tuple<int, int>&)’
test.cpp:16:40: note: candidates are:
/usr/include/c++/4.6/utility:133:5: note: template<unsigned int _Int, class _Tp1, class _Tp2> typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(std::pair<_Tp1, _Tp2>&)
/usr/include/c++/4.6/utility:138:5: note: template<unsigned int _Int, class _Tp1, class _Tp2> const typename std::tuple_element<_Int, std::pair<_Tp1, _Tp2> >::type& std::get(const std::pair<_Tp1, _Tp2>&)
/usr/include/c++/4.6/tuple:531:5: note: template<unsigned int __i, class ... _Elements> typename std::__add_ref<typename std::tuple_element<__i, std::tuple<_Elements ...> >::type>::type std::get(std::tuple<_Elements ...>&)
/usr/include/c++/4.6/tuple:538:5: note: template<unsigned int __i, class ... _Elements> typename std::__add_c_ref<typename std::tuple_element<__i, std::tuple<_Elements ...> >::type>::type std::get(const std::tuple<_Elements ...>&)

那么,有没有什么方法可以将我的枚举类用作 std::get 的模板参数?这是不是不需要编译,而是在 gcc 4.6 中修复的东西?我可以使用一个简单的枚举,但我喜欢枚举类的作用域属性,所以如果可能的话我更愿意使用后者。

最佳答案

C++11 引入的强类型枚举不能隐式转换为类型为 int 的整数值,而 std::get 期望模板参数为为整型。

您必须使用 static_cast 来转换枚举值:

std::cout <<std::get<static_cast<int>(Bad::BAD)>(tup)<< std::endl; //Ok now!

或者您可以选择转换为基础整数类型:

//note that it is constexpr function
template <typename T>
constexpr typename std::underlying_type<T>::type integral(T value) 
{
    return static_cast<typename std::underlying_type<T>::type>(value);
}

然后将其用作:

std::cout <<std::get<integral(Bad::BAD)>(tup)<< std::endl; //Ok now!

关于c++ - std::get 使用枚举类作为模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10742275/

相关文章:

c++ - 使用 cin 读取带有任意空格的逗号分隔整数对 (x,y)

c++ - 为什么确定友元声明是否是其命名空间中的第一个如此重要?

cocoa - 如何在 iPhone 上获取 cocoa 中的 http

c++ - OpenCV 估计刚体变换()

php - 如何在 PHP GET URL 变量(或函数参数)中使用&符号?

php - 制作所有 GET 变量的数组

c++11 - Const 引用 VS move 语义

c++ - 为什么我不能使用带自动的大括号初始化一个值并将它传递给这个函数

c++ - 在 C++ 中创建成员函数模板特化

c++ - 使用 const 引用初始化成员数据