私は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 で修正されたものでしたか? 単純な列挙型を使用することもできますが、enum クラスのスコープ プロパティが好きなので、可能であれば後者を使用したいと思います。