Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare this algorithm?

I want to declare an algorithm that takes a pair of iterators and a criterium. It then returns a vector of items from the range of the iterators which fulfil the criterium.

template <typename TIterator, typename TCriterium>
std::vector< Type that I will get after dereferencing TIterator >
filter (TIterator begin, TIterator end, TCriterium passes);

I can use C++11 features such as decltype or auto. I tried:

#include <vector>

template <typename TIterator, typename TCriterium>
auto filter (TIterator begin, TIterator end, TCriterium passes) 
                      -> std::vector< decltype(*begin) >
{
}

int main()
{
    std::vector<int*> vector;
    filter(vector.begin(), vector.end(), 0);
    return 0;
}

But this doesn't work. I get:

/usr/include/c++/4.7/ext/new_allocator.h:59: 
error: forming pointer to reference type 'int*&'
like image 892
Martin Drozdik Avatar asked Dec 05 '25 10:12

Martin Drozdik


2 Answers

You could use:

std::vector<typename std::iterator_traits<TIterator>::value_type>

As the return type of your function, which would then become:

#include <vector>
#include <iterator>

// ...

template <typename TIterator, typename TCriterium>
std::vector<typename std::iterator_traits<TIterator>::value_type> filter(
    TIterator begin, TIterator end, TCriterium passes)
{
    // Body...
}

If you want to go the decltype way, then you could do:

#include <vector>
#include <type_traits>

// ...

template <typename TIterator, typename TCriterium>
auto filter (TIterator begin, TIterator end, TCriterium passes)
    -> std::vector< typename std::decay<decltype(*begin)>::type >
{
}
like image 187
Andy Prowl Avatar answered Dec 07 '25 00:12

Andy Prowl


*begin is a reference, so you'll need to remove that:

-> std::vector< std::remove_reference<decltype(*vector)>::type >

although, having read the other answers, I'd probably prefer to use iterator_traits here.

like image 35
Mike Seymour Avatar answered Dec 07 '25 00:12

Mike Seymour



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!