Reputation: 131
This may be a duplicate, but I haven't found the problem anywhere else yet. Given the following code:
#include <functional>
#include <algorithm>
#include <iostream>
#include <vector>
template<typename container_ty_>
auto where(container_ty_ const& V, std::function<bool(typename container_ty_::value_type const&)>&& comp)
-> std::vector<std::reference_wrapper<typename container_ty_::value_type>> {
std::vector<std::reference_wrapper<typename container_ty_::value_type>> cursor;
for(typename container_ty_::value_type const& VAL : V)
if(comp(VAL))
cursor.push_back(const_cast<typename container_ty_::value_type&>(VAL));
return cursor;
}
int main(int argc, char** argv) {
std::vector<int> tVect = {0, 5, 2, 1, 7, 9};
//Why must std::vector<int> be passed...
auto vec = where<std::vector<int>>(tVect, [](const int& V) -> bool { return V > 5; });
std::for_each(vec.begin(), vec.end(), [] (int& v) { std::cout << v++ << std::endl; });
std::cout << std::endl;
std::for_each(tVect.begin(), tVect.end(), [](int& v) { std::cout << v << std::endl; });
}
The line where vec
is being assigned, the function where seems to need to have std::vector<int>
passed into it in order to compile. if now i get:
testing.cpp:20:68: error: no matching function for call to ‘
where(std::vector<int>&, main(int, char**)::__lambda0)’ auto vec = where(tVect, [](const int& V) -> bool { return V > 5; });
I suspect this is because the template is not being deduced correctly for the second argument of where
could anyone explain to me why, i seem to be at a standstill...
Also:
Command line args: g++ testing.cpp -g -o testing -std=c++11 -Wall
G++ version: g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
Upvotes: 3
Views: 91
Reputation: 69882
You may be interested in a slightly more flexible version, which:
preserves constness of the values in the source vector (depending on the constness of the vector itself)
Takes any functor, no need for a std::function
-
#include <algorithm>
#include <iostream>
#include <vector>
template<typename container_ty_, class Comp>
auto where(container_ty_& V, Comp&& comp)
{
using value_type = typename container_ty_::value_type;
using reference =
std::conditional_t<
std::is_const<container_ty_>::value,
std::reference_wrapper<const value_type>,
std::reference_wrapper<value_type>
>;
std::vector<reference> cursor;
for(auto& VAL : V)
if(comp(VAL))
cursor.push_back(VAL);
return cursor;
}
int main(int argc, char** argv) {
std::vector<int> tVect = {0, 5, 2, 1, 7, 9};
//Why must std::vector<int> be passed...
auto vec = where(tVect, [](const int& V) -> bool { return V > 5; });
std::for_each(vec.begin(), vec.end(), [] (int& v) { std::cout << v++ << std::endl; });
std::cout << std::endl;
std::for_each(tVect.begin(), tVect.end(), [](const int& v) { std::cout << v << std::endl; });
}
Upvotes: 1
Reputation: 87
If I do not provide the type parameter explicitly I confirm I can reproduce the problem with g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4.
This problem seems to be specific to gcc version 4.8. E.g., the code compiles with newer versions of gcc, and, on the same platform, clang++-3.6 compiles this code with the same command line parameters.
Upvotes: 0