2017-09-12 7 views
5

मैं टैग प्रेषण के बजाय if constexpr का उपयोग करना चाहता हूं, लेकिन मुझे यकीन नहीं है कि इसका उपयोग कैसे किया जाए। नीचे उदाहरण कोड।यदि टैग प्रेषण के बजाय constexpr

template<typename T> 
struct MyTag 
{ 
    static const int Supported = 0; 
}; 

template<> 
struct MyTag<std::uint64_t> 
{ 
    static const int Supported = 1; 
}; 

template<> 
struct MyTag<std::uint32_t> 
{ 
    static const int Supported = 1; 
}; 

class MyTest 
{ 
public: 
    template<typename T> 
    void do_something(T value) 
    { 
     // instead of doing this 
     bool supported = MyTag<T>::Supported; 

     // I want to do something like this 
     if constexpr (T == std::uint64_t) 
      supported = true; 
    } 
}; 
+2

आप नहीं "कहते हैं" कर सकते हैं 'ऑपरेटर ==' प्रकार पर; वह अर्थहीन है। आप बूस्ट हाना जैसे पुस्तकालय के साथ कुछ ऐसा कर सकते हैं: 'if constexpr (hana :: type_c == hana :: type_c ) '। आप 'std :: is_same' का भी उपयोग कर सकते हैं:' यदि constexpr (std :: is_same_v <टी, std :: uint64_t>) ' – Justin

+0

प्रकार मान नहीं हैं, तो आप उनकी तुलना इस तरह नहीं कर सकते हैं। – Rakete1111

+0

@ Rakete1111 हाँ मुझे पता है कि मैं उनकी तुलना इस तरह की तुलना नहीं कर सकता, यही सवाल है कि मुझे यह कैसे करना चाहिए .... और क्यों डाउनवोट? – 0xBADF00

उत्तर

3

एक तरह से एक constexpr विधेय है जो अपने तर्क के प्रकार की जाँच करता है, तो constexpr कि विधेय के परिणाम पर स्विच परिभाषित करने के लिए है।

मुझे लगता है कि यह तरीका अच्छा है क्योंकि यह कार्यात्मक तर्क को पूर्व शर्त तर्क से अलग करता है।

#include <iostream> 
#include <cstddef> 
#include <type_traits> 

class MyTest 
{ 
public: 
    template<typename T> 
    void do_something(T value) 
    { 
     // define our predicate 
     // lambdas are constexpr-if-possible in c++17 
     constexpr auto is_supported = [](auto&& x) { 
      if constexpr (std::is_same<std::decay_t<decltype(x)>, std::uint64_t>()) 
       return true; 
      else 
       return false; 
     }; 

     // use the result of the predicate   
     if constexpr (is_supported(value)) 
     { 
      std::cout << "supported\n"; 
     } 
     else 
     { 
      std::cout << "not supported\n"; 
     } 
    } 
}; 

int main() 
{ 
    auto t = MyTest(); 

    t.do_something(int(0)); 
    t.do_something(std::uint64_t(0)); 
    t.do_something(double(0)); 
    t.do_something(static_cast<unsigned long>(0)); // be careful with std::uint_xx aliases 

} 

उदाहरण परिणाम:

not supported 
supported 
not supported 
supported 

इस हो सकता है व्यक्त करने के लिए एक और तरीका है:

class MyTest 
{ 
public: 

    template<class T> 
    static constexpr bool something_possible(T&&) 
    { 
     return std::is_same<std::decay_t<T>, std::uint64_t>(); 
    } 

    template<typename T> 
    void do_something(T value) 
    { 
     // switch behaviour on result of constexpr predicate  
     if constexpr (something_possible(value)) 
     { 
      std::cout << "supported\n"; 
     } 
     else 
     { 
      std::cout << "not supported\n"; 
     } 
    } 
}; 
+0

बहुत अच्छा जवाब धन्यवाद, और टी टी सूचक या संदर्भ है, तो std :: क्षय की आवश्यकता है, है ना? – 0xBADF00

+0

@ 0xBADF00 क्षय, संदर्भ इत्यादि से क्षय स्ट्रिप्स, ताकि आप अंतर्निहित प्रकारों की तुलना कर सकें। –

संबंधित मुद्दे