c++ - मैं संकलन-समय के दौरान प्रकार / स्विच प्रकार कैसे बदलूं?




templates c++11 compile-time typetraits (5)

क्या सी ++ 11 में एक हस्ताक्षरित अनुक्रमणिका पर संकलन-समय पर एक प्रकार का चयन करने के लिए मेरे लिए एक मानक तरीका है?

उदाहरण के लिए, कुछ ऐसा:

using type_0 = static_switch<0,T,U>;  // yields type T
using type_1 = static_switch<1,T,U>;  // yields type U

यदि एक वैरिएडिक-टेम्पलेट संस्करण है, तो यह बहुत उपयोगी होगा।


Answers

सी ++ 17 के साथ आप इस और तरीके से भी जा सकते हैं। इस प्रकार की गणना की बजाय स्पष्ट रूप से आप constexpr if उपयोग कर सकते हैं और अलग-अलग चीजें (विभिन्न प्रकारों को वापस करने सहित) सीधे कर सकते हैं:

template<size_t N>
decltype(auto) foo(){
  if constexpr(N%2==0){
      return std::string("Hello I'm even");
  }else{
      return std::pair(
           std::vector<char>{'O','d','d',' ','v','a','l','u','e'},
           [](){ return N; });         
  }
}

foo<0>()           // "Hello I'm even"
foo<21>().second() // 21

आप इसे केवल प्रकार प्राप्त करने के लिए भी उपयोग कर सकते हैं:

using type_0 = decltype(foo<0>());
using type_1 = decltype(foo<1>());

कैसा रहेगा

 template<size_t N, typename T, typename U>
 struct static_switch {};

 template<typename T, typename U>
 struct static_switch<0, T, U>{typedef T type;};

 template<typename T, typename U>
 struct static_switch<1, T, U>{typedef U type;};

आप इसे निम्नानुसार उपयोग करेंगे:

using type_0 = static_switch<0,T,U>::type;  // yields type T
using type_1 = static_switch<1,T,U>::type;  // yields type U

यह std::conditional में आपके लिए कम या ज्यादा लागू किया गया है।


यह काम करना चाहिए:

template<std::size_t N, typename... T>
using static_switch = typename std::tuple_element<N, std::tuple<T...> >::type;

एक और तरीका:

template<std::size_t N, typename T, typename... Ts>
struct static_switch {
  using type = typename static_switch<N - 1, Ts...>::type;
};
template<typename T, typename... Ts>
struct static_switch<0, T, Ts...> {
  using type = T;
};

आप अपने प्रकार को स्टोर करने के लिए boost::mpl::vector का उपयोग कर सकते हैं और सूचकांक से एक प्रकार प्राप्त करने के लिए boost::mpl::at<v,n>::type उपयोग कर सकते हैं।

template<std::size_t N, typename... T>
using static_switch = typename boost::mpl::at<boost::mpl::vector<T...>, N>::type;

मैक पर g ++ का उपयोग करके मैंने अपने कंप्यूटर पर मूल परिणाम दोहराया।

निम्न लूप को C ++ संस्करण में जोड़ने से ठीक पहले लूप इसे Python संस्करण के साथ इनलाइन लाता है:

std::ios_base::sync_with_stdio(false);
char buffer[1048576];
std::cin.rdbuf()->pubsetbuf(buffer, sizeof(buffer));

sync_with_stdio बेहतर गति 2 सेकंड तक, और एक बड़ा बफर सेट करने से इसे 1 सेकंड तक लाया गया।





c++ templates c++11 compile-time typetraits