std :: get使用枚举类作为模板参数 [英] std::get using enum class as template argument

查看:438
本文介绍了std :: get使用枚举类作为模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using a std::tuple and defined a class enum to somehow "naming" each of the tuple's fields, forgetting about their actual indexes.

而不是这样:

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版本,我的项目无法编译。此代码段重现错误:

The problem is that, as this compiled using gcc 4.5.2, I've now installed the 4.6.1 version, and my project failed to compile. This snippet reproduces the error:

#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

The error basically says that there's no overload that matches my call to 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?我可以使用一个简单的枚举,但我喜欢枚举类的范围属性,所以我喜欢使用后者,如果可能。

So, is there any way I can use my enum class as a template argument to std::get? Was this something that wasn't ment to compile, and was fixed in gcc 4.6? I could use a simple enum, but I like the scoping properties of enum classes, so I'd prefer to use the latter if it's possible.

推荐答案

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

The strongly-typed enums introduced by C++11 cannot be implicitly converted into integral values of type say int, while std::get expects the template argument to be integral type.

你必须使用 static_cast 转换枚举值:

You've to use static_cast to convert the enum values:

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

或者您可以选择转换为基本积分类型:

Or you can choose to convert into underlying integral type as:

//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!

这篇关于std :: get使用枚举类作为模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆