2017-02-21 9 views
3

yieldのファミリでは、どのような理由からデフォルトのコンストラクタが必要なのかについて理解しようとしていますか?range-v3 yieldにデフォルトのコンストラクタが必要なのはなぜですか?

次の例では、vnums1行は、CNumにデフォルトコンストラクタがある場合にのみコンパイルされます。 vnums2行には、デフォルトのコンストラクタは必要ありません。

私はVisual Studio 2017とRange-V3-VS2015を使用しています。ありがとうございました!

#include <range/v3/all.hpp> 

struct CNum 
{ 
    // CNum() = default; 
    explicit CNum(int num) : m_num(num) {} 
    int m_num; 
}; 

int main() 
{ 
    auto ints = ranges::view::ints(0, 10); 

    // this compiles only of CNum has a default constructor 
    auto vnums1 = ints 
     | ranges::view::for_each([](int num) { return ranges::yield_if(num % 2, CNum(num)); }) 
     | ranges::to_vector; 

    // this compiles even if CNum does not have a default constructor 
    auto vnums2 = ints 
     | ranges::view::remove_if([](int num) { return num % 2 == 0; }) 
     | ranges::view::transform([](int num) { return CNum(num); }) 
     | ranges::to_vector; 

    return 0; 
} 

答えて

2

私は、DefaultConstructibleを必要としないようにコードを変更しました。 gitを引っ張って楽しんでください。

+0

これは素晴らしいことです。ありがとうございました。 Microsoft/Range-V3-VS2015のメンテナはericniebler/range-v3から新しい変更を取得していません。 VC++ 2017で動作する最新のビットをどうやって得ることができるかについて誰かが提案していますか? – CodeAndLearn

+0

悲しいことに、Microsoft/Range-V3-VS2015レポをフォークして、自分で変更を加えることをお勧めします。 –

1

あなたがranges::yield_ifを使用するようにコンストラクタをデフォルトする必要がある理由は、それが使用する機械は、デフォルト構築可能であることをタイプを必要とすることです。コードを見れば、

struct yield_if_fn 
{ 
    template<typename V> 
    repeat_n_view<V> operator()(bool b, V v) const 
    { 
     return view::repeat_n(std::move(v), b ? 1 : 0); 
    } 
}; 

/// \relates yield_if_fn 
/// \ingroup group-views 
RANGES_INLINE_VARIABLE(yield_if_fn, yield_if) 

view::repeat_nがあります。そのコードを見てみると、私たちは

repeat_n_view<Val> operator()(Val value, std::ptrdiff_t n) const 
{ 
    return repeat_n_view<Val>{std::move(value), n}; 
} 

を取得し、我々はrepeat_n_viewを見れば、私たちは私たちが、これは設計上の決断だったとこの設計のため、あなたがするあなたのタイプを必要とすることをコメントから見

// Ordinarily, a view shouldn't contain its elements. This is so that copying 
// and assigning ranges is O(1), and also so that in the event of element 
// mutation, all the copies of the range see the mutation the same way. The 
// repeat_n_view *does* own its lone element, though. This is OK because: 
// - O(N) copying is fine when N==1 as it is in this case, and 
// - The element is immutable, so there is no potential for incorrect 
// semantics. 

struct repeat_n_view 
    : view_facade<repeat_n_view<Val>, finite> 
{ 
private: 
    friend range_access; 
    Val value_; 
    std::ptrdiff_t n_; 

    // ... 
public: 
    repeat_n_view() = default; 
    constexpr repeat_n_view(Val value, std::ptrdiff_t n) 
     : value_(detail::move(value)), n_((RANGES_EXPECT(0 <= n), n)) 
    {} 
    constexpr std::size_t size() const 
    { 
     return static_cast<std::size_t>(n_); 
    } 
}; 

を持っていますデフォルト構築可能。 Ericは、SemiRegularとして必要とされるタイプを、

として記述しています。これは、デフォルトで構成可能であり、コピー可能であり、構成可能であり、破壊可能でなければなりません。

関連する問題