6

のような関数を書こうとしていますがstd::for_each、通常の使用法に加えて、std::function<bool (param)>. false の戻り値は、ループから抜け出したいことを意味します。以下のコードは、これまでに取得したものです。

2 番目の呼び出しa.visit([&](int) -> void)は、!visitor(i) を評価するときにコンパイルされません。これを機能させることは可能ですか、それとも間違ったツリーを吠えていますか?

私は MSVC 2010 を使用していますが、コードを一般的に C++11 互換にしたいと考えています。

#include <list>
#include <string>
#include <iostream>

struct A 
{
    std::list<int> _lst;

    template<typename _F>
    void visit(_F visitor) 
    {
        for(std::list<int>::const_iterator it = _lst.begin(), end = _lst.end() ; it != end ; it++) {
            int i = *it;
            if (std::is_void<decltype(visitor(i))>::value) {
                visitor(i);
            } else {
               if (!visitor(i)) { // <----- error C2171: '!' : illegal on operands of type 'void'
                   break;
               }
            }
        }
    }

};

int main(int argc, char* argv[])
{
    A a;
    // populate a
    for (int i = 0 ; i < 10 ; i++) { 
        a._lst.push_back(i); 
    }

    a.visit([](int i) -> bool {
        std::cout << i << std::endl;
        return i < 5;
    });

    a.visit([](int i) {
        std::cout << i << std::endl;
    });
}
4

3 に答える 3

6

実装方法は次のとおりfor_almost_eachです。using namespace std読みやすくするために、型エイリアスを追加しています。

#include <algorithm>
#include <iterator>
#include <functional>

using namespace std;

template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::true_type)
{
    for (auto i = begin; i!=end; ++i)
        if (!func(*i))
            return i;
    return end;
}

template<class Iter, class Func>
Iter
for_almost_each_impl(Iter begin, Iter end, Func func, std::false_type)
{
    for_each(begin, end, func);
    return end;
}


template<class Iter, class Func>
Iter for_almost_each(Iter begin, Iter end, Func func)
{
    using Val = typename iterator_traits<Iter>::value_type;
    using Res = typename result_of<Func(Val)>::type;
    return for_almost_each_impl(begin, end,
                                func,
                                is_convertible<Res, bool>{} );
}

is_convertibleよりも理にかなっているように見えるので、私は を使用しましたis_same

于 2013-10-01T02:57:48.880 に答える
-1

このラムダは値を返さないため、「訪問者」が void を返しているというエラーが発生します。

a.visit([](int i) {
    std::cout << i << std::endl;
});

次のように書き直すことで、これを機能させることができます。

a.visit([](int i) -> bool {
    std::cout << i << std::endl;
    return true;
});
于 2013-10-01T01:55:07.430 に答える