2015-05-04 62 views
1

採取的答案從這裏:iterate over tuple關於打印std::tuple成分,這裏是代碼:視覺工作室 - 性病解決方法錯誤c2770 :: enable_if

template<std::size_t I = 0, typename... Tp> 
typename std::enable_if<I == sizeof...(Tp), void>::type 
print(const std::tuple<Tp...>& t) 
{ } 

template<std::size_t I = 0, typename... Tp> 
typename std::enable_if<I < sizeof...(Tp), void>::type 
    print(const std::tuple<Tp...>& t) 
{ 
    std::cout << std::get<I>(t) << std::endl; 
    print <i, Tp...> (t); 
} 

此編譯和完美的作品在GCC,但無法編譯在VC++(我使用Visual Studio 2013)。錯誤我在流汗:

Error 4 error C2893: Failed to specialize function template 'std::enable_if<I==1,void>::type print(const std::tuple<_Types1...> &)' 
Error 3 error C2770: invalid explicit template argument(s) for 'std::enable_if<I<1,void>::type print(const std::tuple<_Types1...> &)' 

appearntly上有C2770一中的缺陷利用std::enable_if具有明確的模板參數時。一些開發商利用const int作爲預參數爲模板

const int i = I+1; 
print<i,Tp...>(t); 

推薦但這也不管用。 還有其他的解決方案,如使用一些宏,但它們也失敗了。
有人有解決它的方法嗎?我搜索了一個解決方案,但沒有發現任何實際的工作。
謝謝。

+0

工作對我來說在VS2015 RC。發佈(希望)即將推出,所以工具鏈升級可能是非標準的,但也是可行的選擇。 (在VS2015中甚至沒有提到'constexpr',更快的編譯和鏈接等) – Drop

+0

感謝他們修正了它:) :) –

回答

1

您可以使用以下中的一個:使用遞減遞歸和(部分)專業化

  • namespace detail 
    { 
        template <std::size_t N> 
        struct printer 
        { 
         template <typename TUPLE> 
         void operator() (const TUPLE& t) const 
         { 
          printer<N - 1>{}(t); 
          std::cout << std::get<N - 1>(t) << std::endl; 
         } 
        }; 
    
        template <> 
        struct printer<0> 
        { 
         template <typename TUPLE> 
         void operator() (const TUPLE& t) const {} 
        }; 
    
    } 
    
    
    template <typename ... Ts> 
    void print(const std::tuple<Ts...>& t) 
    { 
        detail::printer<sizeof...(Ts)>{}(t); 
    } 
    
  • ,或者使用index_sequence

    #if 1 // Not in C++11 
    #include <cstdint> 
    
    template <std::size_t...> struct index_sequence {}; 
    
    template <std::size_t N, std::size_t... Is> 
    struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {}; 
    
    template <std::size_t... Is> 
    struct make_index_sequence<0u, Is...> : index_sequence<Is...>{}; 
    
    #endif 
    
    namespace detail 
    { 
    
        template <std::size_t... Is, typename TUPLE> 
        void print(const TUPLE& t, index_sequence<Is...>) 
        { 
         int dummy[] = {0, ((std::cout << std::get<Is>(t) << std::endl), 0)...}; 
         (void) dummy; // To remove warning about unused variable. 
        } 
    
    } 
    
    template <typename ... Ts> 
    void print(const std::tuple<Ts...>& t) 
    { 
        detail::print(t, make_index_sequence<sizeof...(Ts)> {}); 
    } 
    
+0

我沒有試過第二個代碼片段,但第一個defintly的作品。謝謝。 –

1

要保留這個問題給出的原始代碼的結構,下面的解決辦法適用於我在MSVC 2013:

定義下列助手:

// workaround for msvc `sizeof...(Tp)` not working 
template<typename... Tp> 
struct sizeof_pack___ { static const std::size_t value = sizeof...(Tp); }; 

然後用sizeof_pack___<Tp...>::value取代的sizeof...(Tp)出現的兩個。

最後的代碼應該是這樣的:

template<std::size_t I = 0, typename... Tp> 
typename std::enable_if<I == sizeof_pack___<Tp...>::value, void>::type 
    print(const std::tuple<Tp...>& t) 
{ } 

template<std::size_t I = 0, typename... Tp> 
typename std::enable_if<I < sizeof_pack___<Tp...>::value, void>::type 
    print(const std::tuple<Tp...>& t) 
{ 
    std::cout << std::get<I>(t) << std::endl; 
    print <i, Tp...> (t); 
}