2017-09-12 12 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

あなたはタイプの '演算子==' "コール" することはできません。それは無意味です。あなたはboost hana: 'if constexpr(hana :: type_c == hana :: type_c )'のようなライブラリで同様のことをすることができます。 'std :: is_same'を使うこともできます:' constexpr(std :: is_same_v ) ' – 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

ありがとう非常に良い答え、そしてTはポインタまたは参照、右の場合は、std :: decayが必要ですか? – 0xBADF00

+0

@ 0xBADF00 decayはconst、referenceなどを取り除き、基になる型を比較す​​ることができます。 –

関連する問題