2017-12-28 17 views
0

std::tupleのすべての要素が特定の条件を満たすかどうかを検証しようとしています。折り畳み式ではない(まだ)実装されているので、すべてのstd :: tuple要素が条件+設計上の問題を満たしているかどうか確認してください

template <typename F, typename Tuple, size_t...Is> 
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t, std::index_sequence<Is...>) { 
    return (std::forward<F>(fn)(std::get<Is>(std::forward<Tuple>(t))) && ...); 
} 

template <typename F, typename Tuple> 
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t) { 
    return tuple_all_of(std::forward<F>(fn), std::forward<Tuple>(t), 
     std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>()); 
} 

それは、最新の打ち鳴らすとgccでコンパイルしますが、MSVCで失敗します。私の現在のソリューションは、C++ 17倍epxressionsを使用しています。 (https://blogs.msdn.microsoft.com/vcblog/2017/05/10/c17-features-in-vs-2017-3/

折り畳み式を使用しないで同様のソリューションがありますか?


これは、使用されることになっています方法です:

template<typename...Components, typename Callable> 
    void FindComponents(Callable&& fn) { 
     for (auto& node : m_Entities) { 
      auto tp = std::make_tuple(node.GetComponent<Components>()...); 
      if (!tuple_all_of([](auto& p) { return p != nullptr; }, tp)) 
       continue; 

      apply_from_tuple(fn, tp); 
     } 
    } 

ノードが接続要求されたコンポーネント(すなわちGetComponent = nullptrを!)がある場合にのみ、だから私はfnを呼び出しています。たぶん、より良い解決策がありますか?

あなたがより簡単にタプルを解凍する std::applyを使用することができ
+1

MSVC 2017.5は、私の知る限りでは、式を折る含まれています。 – DeiDei

答えて

0

template <typename F, typename Tuple> 
constexpr bool tuple_all_of(F&& fn, const Tuple& t) 
{ 
    return std::apply([&fn](const auto&... xs) 
    { 
     return (fn(xs) && ...); 
    }, t); 
} 

倍表現for_each_argumentに置き換えることができます。

template <typename F, typename Tuple> 
constexpr bool tuple_all_of(F&& fn, const Tuple& t) 
{ 
    bool result = true; 
    std::apply([&](const auto&... xs) 
    { 
     for_each_argument([&](const auto& x) 
     { 
      if(fn(x)) result = false; 
     }, xs...); 
    }, t); 
    return result; 
} 

template <class F, class... Ts> 
void for_each_argument(F f, Ts&&... a) 
{ 
    (void)std::initializer_list<int>{(f(std::forward<Ts>(a)), 0)...}; 
} 
2

Visual C++ Language Conformanceによると、 VS2017 15.5から/std:c++17(または/std:c++latest)コンパイラオプションを使用してサポートされています。

0

私は[注意:コードテストされていません]あなたは未使用のCスタイルの配列の初期化の古いトリックを使用することができたと

template <typename F, typename Tuple, size_t...Is> 
_CR_INLINE bool tuple_all_of(F&& fn, Tuple&& t, std::index_sequence<Is...>) { 
    using unused=bool[]; 

    bool ret { true }; 

    (void)unused { true, (ret = ret && std::forward<F>(fn)(std::get<Is>(std::forward<Tuple>(t)))) ... }; 

    return ret; 
} 
関連する問題