2017-12-28 18 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/)

fold expression을 사용하지 않고 비슷한 해결책이 있습니까?


사용해야하는데 방법은 다음과 같습니다

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를 호출하고 있습니다. 어쩌면 더 나은 해결책이 있을까요?

+1

MSVC 2017.5는 내가 아는 한 표현을 배 포함 [주의 코드는 테스트하지]. – DeiDei

답변

0

당신은 더 쉽게 튜플을 풀고 std::apply을 사용할 수는 :

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)...}; 
} 
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; 
}