2014-10-26 60 views
0

有人可以改進我的這個功能嗎? enumToSTLContainer將返回其元素來自指定枚舉列表的任何STL容器。STL容器的枚舉列表

#include <iostream> 
#include <vector> 
#include <set> 

enum MyEnum {A, B, C, D, E, FirstMyEnum = A, LastMyEnum = E}; 

template <typename CONTAINER> 
CONTAINER enumToSTLContainer (typename CONTAINER::value_type first, typename CONTAINER::value_type last) { 
    CONTAINER v; 
    for (typename std::underlying_type<typename CONTAINER::value_type>::type N = first; N <= last; N++) 
     v.push_back(static_cast<typename CONTAINER::value_type>(N)); // But only works for STL containers with push_back defined. 
    return v; 
} 

int main() { 
    const std::vector<MyEnum> enumVector = enumToSTLContainer<std::vector<MyEnum>> (FirstMyEnum, LastMyEnum); 
    for (MyEnum x : enumVector) 
     std::cout << x << ' '; // 0 1 2 3 4 
// const std::set<MyEnum> enumSet = enumToSTLContainer<std::set<MyEnum>> (FirstMyEnum, LastMyEnum); // won't compile 
} 

上述問題。僅適用於定義了push_back的STL容器,需要指定枚舉列表的第一個和最後一個元素,如果枚舉值不連續,則不起作用...

也許使用可變參數模板獲取initializer_list,然後可以返回所需的STL容器?使用std :: integer_sequence從枚舉中取出一個元組,或者在它們不是連續的情況下創建與枚舉元素相對應的自己的integer_sequence?

+0

這個問題似乎是題外話,因爲它是關於改進代碼,並會在http得到更好的服務://codereview.stackexchange .com – 2014-10-26 15:51:23

+0

你想要一個範圍如'enum {a,b = 100};'? – 2014-10-26 15:55:10

+0

這就是爲什麼我的功能需要嚴肅的改進才能工作。 @Captain無知,我的代碼只是一個(可憐的)建議,以解決方案開始。我實際上是在尋求想法和方法。 – prestokeys 2014-10-26 15:58:31

回答

1

好吧,我得到了以下所需的屬性,但它使用的假設是枚舉底層值從零開始並且是連續的。解決方案是使用C++ 11而不是C++ 14,這樣每個人都可以編譯它。

#include <iostream> 
#include <vector> 
#include <set> 

enum MyEnum {A, B, C, D, E, NumElements}; 

template <std::size_t...> struct index_sequence {}; 

template <std::size_t N, std::size_t... Is> 
struct make_index_sequence_helper : make_index_sequence_helper<N-1, N-1, Is...> {}; 

template <std::size_t... Is> 
struct make_index_sequence_helper<0, Is...> { 
    using type = index_sequence<Is...>; 
}; 

template <std::size_t N> 
using make_index_sequence = typename make_index_sequence_helper<N>::type; 

template <typename RETURN_TYPE, std::size_t... TYPES> 
inline RETURN_TYPE helper (index_sequence<TYPES...>) { 
    return {static_cast<typename RETURN_TYPE::value_type>(TYPES)...}; 
} 

template <typename CONTAINER, std::size_t N> 
CONTAINER enumToSTLContainer() { 
    return helper<CONTAINER> (make_index_sequence<N>()); 
} 

int main() { 
    const std::vector<MyEnum> enumVector = enumToSTLContainer<std::vector<MyEnum>, NumElements>(); 
    for (MyEnum x : enumVector) 
     std::cout << x << ' '; // 0 1 2 3 4 
    const std::set<MyEnum> enumSet = enumToSTLContainer<std::set<MyEnum>, NumElements>(); 
    std::cout << "\n\n"; 
    for (MyEnum x : enumSet) 
     std::cout << x << ' '; // 0 1 2 3 4 
} 

所以在第二種解決方案中,我們不再僅限於具有push_back的STL容器。希望如果有人能告訴我如何改進這種解決方案,枚舉底層值不連續。理想情況下NumElements也不需要。我認爲只有make_index_sequence_helper需要根據MyEnum基礎值進行修改?

,我能想出的唯一的泛化是糟糕:

template <typename CONTAINER, std::size_t... Is> 
CONTAINER enumNonContiguousToSTLContainer() { 
    return helper<CONTAINER> (index_sequence<Is...>()); 
}