I saw this example of how to do it in C++11:
std::unique(v.begin(), v.end(), [](float l, float r)
{
return std::abs(l - r) < 0.01;
});
However, this fails for me in C++03:
error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'CRayTracer::myFunc()::<lambda(float, float)>'
How can I do this in C++03? I think Lambdas may have already existed, and functors/function objects existed, right? Just looking for a simple solution, does not need to be extendable - it will only ever be used here.
Here is an example of code which will not compile for me:
#include <iostream>
#include <vector>
#include <algorithm>
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
struct approx_equal
{
bool operator()(float l, float r)
{
return std::abs(l - r) < 0.01;
}
};
approx_equal f;
std::unique(v.begin(), v.end(),f);
}
Here's the error it produced:
testUnique.cpp: In function 'int main()':
testUnique.cpp:21:37: error: no matching function for call to 'unique(std::vector<float>::iterator, std::vector<float>::iterator, main()::approx_equal&)'
21 | std::unique(v.begin(), v.end(),f);
| ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note: candidate: 'template<class _FIter> _FIter std::unique(_FIter, _FIter)'
995 | unique(_ForwardIterator __first, _ForwardIterator __last)
| ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:995:5: note: template argument deduction/substitution failed:
testUnique.cpp:21:37: note: candidate expects 2 arguments, 3 provided
21 | std::unique(v.begin(), v.end(),f);
| ^
In file included from C:/msys64/mingw64/include/c++/9.2.0/algorithm:62,
from testUnique.cpp:3:
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note: candidate: 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'
1025 | unique(_ForwardIterator __first, _ForwardIterator __last,
| ^~~~~~
C:/msys64/mingw64/include/c++/9.2.0/bits/stl_algo.h:1025:5: note: template argument deduction/substitution failed:
testUnique.cpp: In substitution of 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate) [with _FIter = __gnu_cxx::__normal_iterator<float*, std::vector<float> >; _BinaryPredicate = main()::approx_equal]':
testUnique.cpp:21:37: required from here
testUnique.cpp:21:37: error: template argument for 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)' uses local type 'main()::approx_equal'
21 | std::unique(v.begin(), v.end(),f);
| ^
testUnique.cpp:21:37: error: trying to instantiate 'template<class _FIter, class _BinaryPredicate> _FIter std::unique(_FIter, _FIter, _BinaryPredicate)'
And here was my set of flags:
g++ -c -g -O3 -Wp,-D_FORTIFY_SOURCE=2 -m64 -Wshadow -Wall -DMX_COMPAT_32 -fexceptions -fno-omit-frame-pointer -D__WIN32__ -std=c++03 testUnique.cpp -o testUnique.o
I think Lambdas may have already existed,
No. Lambdas have been introduced in C++11.
... and functors/function objects existed, right?
Functors are simply objects with an operator(), so they always have been there (though not sure when the term "functor" was actually introduced for them).
For the formal correct way to put it I refer you to other references, sloppy speaking this
auto f = [](float l, float r){
return std::abs(l - r) < 0.01;
};
f(0.1,0.2);
Is equivalent to
struct unnamed {
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
unnamed f;
f(0.1,0.2);
I.e. you can always replace a lambda with a handwritten functor class. Create an instance of the functor and pass that instead of the lambda.
Complete example:
#include <iostream>
#include <vector>
#include <algorithm>
struct approx_equal{
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
int main(){
std::vector<float> v{1.0, 1.0, 3.5, 3.5 };
approx_equal f;
v.erase(std::unique(v.begin(), v.end(),f),v.end());
// sorry this is c++11, replace with iterator loop to see output pre-c++11
for (const auto& x : v) std::cout << x << " ";
}
PS: In C++03 you cannot define the functor class locally and then use it as template parameter (note you do not explicitly pass it as template parameter, but unique has to deduce its type from the parameter you pass in).
Lambdas don't exist in C++03, they were introduced in C++11.
Since your lambda example does not need to capture values, you can replace it with a simple standalone function, you don't need a functor, eg:
#include <iostream>
#include <vector>
#include <algorithm>
bool approx_equal(float l, float r) {
return std::abs(l - r) < 0.01;
}
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
std::unique(v.begin(), v.end(), approx_equal);
}
However, you can use a functor, too. In your attempt to use a functor, you simply defined the functor type inside of main() itself, making it a local type, which the compiler complained about. Define the functor type in global scope instead (you can still use a local variable to instantiate the type), eg:
#include <iostream>
#include <vector>
#include <algorithm>
struct approx_equal {
bool operator()(float l, float r) {
return std::abs(l - r) < 0.01;
}
};
int main(){
std::vector<float> v;
v.push_back(1.0);
v.push_back(1.0);
v.push_back(3.5);
v.push_back(3.5);
approx_equal f;
std::unique(v.begin(), v.end(), f);
// or:
// std::unique(v.begin(), v.end(), approx_equal{});
}
Related
I'm using a template function, which the goal is reciever a vector and a function, and return the function type.
template <typename T, typename Function>
auto apply(const std::vector<T>& V, const Function &F){
vector<Function> x; # ERROR HERE
return x;
}
But the IDE give me error (http://coliru.stacked-crooked.com/a/ee6ce2127e013a18):
/usr/local/include/c++/10.2.0/ext/new_allocator.h: In instantiation of 'class __gnu_cxx::new_allocator<double(double)>':
/usr/local/include/c++/10.2.0/bits/allocator.h:116:11: required from 'class std::allocator<double(double)>'
/usr/local/include/c++/10.2.0/bits/stl_vector.h:87:21: required from 'struct std::_Vector_base<double(double), std::allocator<double(double)> >'
/usr/local/include/c++/10.2.0/bits/stl_vector.h:389:11: required from 'class std::vector<double(double), std::allocator<double(double)> >'
main.cpp:10:22: required from 'auto apply(const std::vector<T>&, const Function&) [with T = int; Function = double(double)]'
main.cpp:19:39: required from here
/usr/local/include/c++/10.2.0/ext/new_allocator.h:96:7: error: 'const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::const_pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::const_reference = double (&)(double)]' cannot be overloaded with '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::reference = double (&)(double)]'
96 | address(const_reference __x) const _GLIBCXX_NOEXCEPT
| ^~~~~~~
/usr/local/include/c++/10.2.0/ext/new_allocator.h:92:7: note: previous declaration '_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = double(double); __gnu_cxx::new_allocator<_Tp>::pointer = double (*)(double); __gnu_cxx::new_allocator<_Tp>::reference = double (&)(double)]'
92 | address(reference __x) const _GLIBCXX_NOEXCEPT
| ^~~~~~~
main.cpp: In function 'int main(int, char**)':
main.cpp:19:31: error: conversion from 'vector<double(double),allocator<double(double)>>' to non-scalar type 'vector<double,allocator<double>>' requested
19 | vector<double> r = ::apply(v, seno);
| ~~~~~~~^~~~~~~~~
This is call of the main function.
double seno( double n ) { return sin(n); }
int main( int argc, char* argv[]) {
vector<int> v{ 1, 2, 3, 4, 5 };
vector<double> r = ::apply(v, seno);
cout << r;
return 0;
}
I don't know what I'm doing wrong, so How can I improve this method and pass trough this error?
EDIT: The purpse to generalize the in method insted of using double in the vector is because I want o re-use in another way. So I've generalize the most that I can.
vector<Function> x; // ERROR HERE defines a vector of function pointers. But that's not what you want - you want a vector of the return type of the function. And that's what decltype() is for.
In your apply function, F is the function to be called and T is the type of the values in the vector being passed in. That means T() is the default value of the items in the vector (in this case the default value of int is 0). Then, F(T()) would actually call the function with 0 and return something so decltype(F(T())) tells you the type of the thing returned.
That means you need to write vector<decltype(F(T()))> x; instead.
T() works because the type is int and it is default constructible. As #alterigel said in the comments std::declval<T>() is better when the type is not default constructible.
So vector<decltype(F(std::declval<T>()))> x; might be needed in some situations.
The whole program would look like:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
template <typename T, typename Function>
auto apply(const std::vector<T>& V, const Function &F) {
vector<decltype(F(T()))> x;
for(auto a : V)
x.push_back(F(a));
return x;
}
double seno( double n ) { return sin(n); }
int main( int argc, char* argv[]) {
vector<int> v{ 1, 2, 3, 4, 5 };
vector<double> r = ::apply(v, seno);
for (auto a : r)
cout << a << " ";
return 0;
}
Try it here: https://onlinegdb.com/SknTsVaHO
I want to search an input range for an element that has a certain value in a member via an accessor.
range-v3 documentation is... thin, but there are sources such as this answer by AFAIK the 2 main range-v3 developers indicates this kind of thing should Just Work, albeit with sort not find.
Given the code, compiled with g++ -std=c++17 against ericniebler/range-v3 release range-v3-0.10.0, using g++.exe (Rev2, Built by MSYS2 project) 9.3.0:
#include <range/v3/algorithm/find.hpp>
#include <vector>
auto
main() -> int
{
struct S {
int i{};
auto get_i() const { return i; }
};
auto const ss = std::vector<S>(10);
ranges::find(ss, 1, &S::get_i);
return 0;
}
I get a spew of errors:
test.cpp: In function 'int main()':
test.cpp:14:31: error: no match for call to '(const ranges::find_fn) (const std::vector<main()::S>&, int, int (main()::S::*)() const)'
14 | ranges::find(ss, 1, &S::get_i);
| ^
In file included from FOO/include/range-v3/range/v3/range_fwd.hpp:24,
from FOO/include/range-v3/range/v3/algorithm/find.hpp:18,
from test.cpp:1:
FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: candidate: 'template<class I, class S, class V, class P> constexpr concepts::return_t<I, typename std::enable_if<(((input_iterator<I> && sentinel_for<S, I>) && indirect_relation<ranges::equal_to, typename ranges::detail::select_projected_<P>::apply<I>, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(I, S, const V&, P) const'
618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
| ^~~~~~~~
FOO/include/range-v3/range/v3/algorithm/find.hpp:47:24: note: in expansion of macro 'RANGES_FUNC'
47 | constexpr auto RANGES_FUNC(find)(I first, S last, V const & val, P proj = P{})
| ^~~~~~~~~~~
FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: template argument deduction/substitution failed:
618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
| ^~~~~~~~
FOO/include/range-v3/range/v3/algorithm/find.hpp:47:24: note: in expansion of macro 'RANGES_FUNC'
47 | constexpr auto RANGES_FUNC(find)(I first, S last, V const & val, P proj = P{})
| ^~~~~~~~~~~
In file included from FOO/include/range-v3/range/v3/iterator/access.hpp:22,
from FOO/include/range-v3/range/v3/iterator/concepts.hpp:30,
from FOO/include/range-v3/range/v3/algorithm/find.hpp:22,
from test.cpp:1:
FOO/include/range-v3/std/detail/associated_types.hpp: In substitution of 'template<bool B, class T> using enable_if_t = typename ranges::detail::enable_if::apply<T> [with bool B = ranges::readable<std::vector<main()::S> >; T = std::vector<main()::S>]':
FOO/include/range-v3/range/v3/iterator/concepts.hpp:561:19: required by substitution of 'template<class I> using apply = ranges::detail::enable_if_t<(bool)(readable<I>), I> [with I = std::vector<main()::S>]'
FOO/include/range-v3/range/v3/algorithm/find.hpp:48:15: required by substitution of 'template<class I, class S, class V, class P> constexpr concepts::return_t<I, typename std::enable_if<(((input_iterator<I> && sentinel_for<S, I>) && indirect_relation<ranges::equal_to, typename ranges::detail::select_projected_<P>::apply<I>, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(I, S, const V&, P) const [with I = std::vector<main()::S>; S = int; V = int (main()::S::*)() const; P = ranges::identity]'
test.cpp:14:31: required from here
FOO/include/range-v3/std/detail/associated_types.hpp:73:15: error: no class template named 'apply' in 'struct ranges::detail::enable_if<false>'
73 | using enable_if_t = typename enable_if<B>::template apply<T>;
| ^~~~~~~~~~~
In file included from FOO/include/range-v3/range/v3/range_fwd.hpp:24,
from FOO/include/range-v3/range/v3/algorithm/find.hpp:18,
from test.cpp:1:
FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: candidate: 'template<class Rng, class V, class P> constexpr concepts::return_t<typename ranges::detail::if_then<forwarding_range_<R> >::apply<decltype (ranges::_::begin(declval<Rng&>())), ranges::dangling>, typename std::enable_if<((input_range<Rng> && indirect_relation<ranges::equal_to, typename ranges::detail::select_projected_<P1>::apply<decltype (ranges::_::begin(declval<Rng&>()))>, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(Rng&&, const V&, P) const'
618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
| ^~~~~~~~
FOO/include/range-v3/range/v3/algorithm/find.hpp:60:24: note: in expansion of macro 'RANGES_FUNC'
60 | constexpr auto RANGES_FUNC(find)(Rng && rng, V const & val, P proj = P{})
| ^~~~~~~~~~~
FOO/include/range-v3/range/v3/detail/config.hpp:618:27: note: template argument deduction/substitution failed:
618 | #define RANGES_FUNC(NAME) operator() RANGES_FUNC_CONST_ /**/
| ^~~~~~~~
FOO/include/range-v3/range/v3/algorithm/find.hpp:60:24: note: in expansion of macro 'RANGES_FUNC'
60 | constexpr auto RANGES_FUNC(find)(Rng && rng, V const & val, P proj = P{})
| ^~~~~~~~~~~
In file included from FOO/include/range-v3/range/v3/iterator/access.hpp:22,
from FOO/include/range-v3/range/v3/iterator/concepts.hpp:30,
from FOO/include/range-v3/range/v3/algorithm/find.hpp:22,
from test.cpp:1:
FOO/include/range-v3/std/detail/associated_types.hpp: In substitution of 'template<bool B, class T> using enable_if_t = typename ranges::detail::enable_if::apply<T> [with bool B = ranges::indirectly_regular_unary_invocable<int (main()::S::*)() const, __gnu_cxx::__normal_iterator<const main()::S*, std::vector<main()::S> > >; T = ranges::detail::projected_<__gnu_cxx::__normal_iterator<const main()::S*, std::vector<main()::S> >, int (main()::S::*)() const>]':
FOO/include/range-v3/range/v3/iterator/concepts.hpp:552:19: required by substitution of 'template<class Proj> template<class I> using apply = ranges::detail::enable_if_t<(bool)(indirectly_regular_unary_invocable<Proj, I>), ranges::detail::projected_<I, Proj> > [with I = __gnu_cxx::__normal_iterator<const main()::S*, std::vector<main()::S> >; Proj = int (main()::S::*)() const]'
FOO/include/range-v3/range/v3/algorithm/find.hpp:61:15: required by substitution of 'template<class Rng, class V, class P> constexpr concepts::return_t<typename ranges::detail::if_then<forwarding_range_<R> >::apply<decltype (ranges::_::begin(declval<Rng&>())), ranges::dangling>, typename std::enable_if<((input_range<Rng> && indirect_relation<ranges::equal_to, typename ranges::detail::select_projected_<P1>::apply<decltype (ranges::_::begin(declval<Rng&>()))>, const V*>) && concepts::detail::CPP_true(concepts::detail::Nil{})), void>::type> ranges::find_fn::operator()(Rng&&, const V&, P) const [with Rng = const std::vector<main()::S>&; V = int; P = int (main()::S::*)() const]'
test.cpp:14:31: required from here
FOO/include/range-v3/std/detail/associated_types.hpp:73:15: error: no class template named 'apply' in 'struct ranges::detail::enable_if<false>'
73 | using enable_if_t = typename enable_if<B>::template apply<T>;
| ^~~~~~~~~~~
shell returned 1
Making the projection a lambda...
ranges::find( ss, 1, [](auto const& s){ return s.get_i(); } );
...works but seems wasted typing.
Referring directly to the data member...
ranges::find(ss, 1, &S::i);
...works but is not possible if it should be encapsulated behind a const getter, transformer, etc.
What am I doing wrong? Can I not use a pointer-to-member-function as projection? Is it intended?
Edit: clang++ (also on MSYS2) does work here. So I guess this must be a bug in g++. Off to Bugzilla I go... edit: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94973
This is caused by GCC on Windows defaulting to -fms-extensions for compatibility with Microsoft compilers, and that pulling in a non-standard extension that introduces ambiguity between pointers-to-member-data vs -functions written as instance.*member.
We can pass -fno-ms-extensions to stop this and compile such code succesfully, until GCC remove that particular extension, which seems unnecessary and unhelpful nowadays.
Jonathan answered this on my GCC bug 94973:
Jonathan Wakely 2020-05-06 16:26:58 UTC
Aha, the same problem happens on linux if I compile with -fms-extensions
This is the old MS extension that causes x.*f to be accepted when f is a pointer to member function, which should only be valid when used as (x.*f)().
That causes ranges::invoke to think that the projection is a pointer to data member, when actually it's a pointer to member function.
See also PR 94771 comment 4.
Jason, do we want to disable that extension in SFINAE contexts?
Jonathan Wakely 2020-05-06 16:47:42 UTC
They're on by default for mingw, for compatibility with the MS compiler (but in this case it seems the relevant extension is ancient history).
Clang and GCC (except for MSVC) fail to resolve a template argument when it's passed std::addressof<int> as an argument to the template function. The following is an example of such error:
std::vector<int> v{1,2,3,4,5};
std::vector<int*> pv(iv.size());
std::transform(v.begin(), v.end(), pv.begin(), std::addressof<int>);
Clang:
<source>:8:5: error: no matching function for call to 'transform'
std::transform(iv.begin(), iv.end(), piv.begin(), std::addressof<int>);
^~~~~~~~~~~~~~
/opt/compiler-explorer/clang-5.0.0/bin/../include/c++/v1/algorithm:2028:1: note: candidate template ignored: couldn't infer template argument '_UnaryOperation'
transform(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _UnaryOperation __op)
^
GCC:
/opt/compiler-explorer/gcc-7.2.0/include/c++/7.2.0/bits/stl_algo.h:4295:5: note: template argument deduction/substitution failed:
<source>:8:74: note: could not resolve address from overloaded function 'addressof<int>'
std::transform(iv.begin(), iv.end(), piv.begin(), std::addressof<int>);
^
That error would make sense if the argument was instead an std::addressof, because the UnaryOperator template parameter would be ambiguous. However, the compiler doesn't need to deduce what T is in std::addressof<int>, I'd except no ambiguity here.
Here's a working example of my expectations (compiles on Clang 5 and GCC 7.2):
template <typename T>
T* addrof(T& a)
{
return __builtin_addressof(a);
}
template <typename F, typename T>
void foo(F f, T& a)
{
f(a);
}
int main()
{
int a = 42;
foo(addrof<int>, a);
}
My doubt is: why can't std::transforms template argument be deduced from std::addressof<int>?
Yes, it doesn't work in your example because there are two overloads for each template std::addressof since C++ 17 (one getting the address and a deleted version which takes an rvalue reference), and it is ambiguous for the compiler which one to choose. Easiest solution is to use lambda:
#include <vector>
#include <algorithm>
void foo() {
std::vector<int> v{1,2,3,4,5};
std::vector<int*> pv(v.size());
std::transform(v.begin(), v.end(), pv.begin(),
[](int& i) { return std::addressof(i);});
}
Those overloads are listed here: http://en.cppreference.com/w/cpp/memory/addressof
The other option is to use cast, but it is just ugly, and Thy Should Prefer Lambdas! Nevertheless, will provide for completness:
#include <vector>
#include <algorithm>
void foo() {
std::vector<int> v{1,2,3,4,5};
std::vector<int*> pv(v.size());
std::transform(v.begin(), v.end(), pv.begin(),
static_cast<int* (*)(int&) >(std::addressof<int>));
}
I am trying to solve a simple Fibonacci problem using the lambda function, but I came across this error and I cant solve it.
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
string str;
auto N{0};
auto i{0};
cout<<"Digite o valor de N desejado: ";
getline(cin,str); //pega linha
stringstream(str) >> N;
if (N == 0){cout<<0;}
else if (N == 1){cout<<1;}
else
{
vector<int> v{0,1}; //cria vetor v
for_each(v.begin(),N,
[&](){
v.push_back(v[i]+v[i+1]);
i++;
});
i = 0;
for_each(v.begin(),N,
[&](){
cout<<v[i];
i++;
});
}
return 0;
}
And the error is the following:
quest1.cpp: In function ‘int main()’: quest1.cpp:30:4: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’ });
^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: template argument deduction/substitution failed: quest1.cpp:30:4: note: deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’) });
^ quest1.cpp:38:5: error: no matching function for call to ‘for_each(std::vector<int>::iterator, int&, main()::<lambda()>)’
});
^ In file included from /usr/include/c++/6.3.1/algorithm:62:0,
from quest1.cpp:5: /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: candidate: template<class _IIter, class _Funct> _Funct std::for_each(_IIter,
_IIter, _Funct)
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
^~~~~~~~ /usr/include/c++/6.3.1/bits/stl_algo.h:3763:5: note: template argument deduction/substitution failed: quest1.cpp:38:5: note: deduced conflicting types for parameter ‘_IIter’ (‘__gnu_cxx::__normal_iterator<int*, std::vector<int> >’ and ‘int’)
});
There's two problems in your code. One (already covered by other answers), you're passing the number of iterations as the second parameter to std::for_each, but it actually expects an end iterator. std::for_each(a, b, f) is designed to iterate from iterator a to iterator b and call f on each element in that range.
The second problem is more fundamental: if you modify the vector while iterating over it, you'll get Undefined Behaviour because any modification operation invalidates all iterators to the vector.
Looking at your code, it seems you want the first loop to a normal counting loop and not iteration over the container. The second loop could be done with for_each and a lambda:
vector<int> v{0,1};
for (int i = 0; i < N; ++i) {
v.push_back(v[i] + v[i+1]);
}
for_each(v.begin(), v.end(),
[](int element) {
cout << element;
}
);
Notice that the functor used in for_each is not nullary: the algorithm will pass the element to it.
Alternatively, the printing functionality could be implemented without lambdas:
copy(v.begin(), v.end(), ostream_iterator<int>(cout));
Or, if you prefer to keep the loop, you could just as well use a range-based for loop instead of for_each. The code will be shorter and [subjective]easier to read[/subjective]:
for (int elem : v) {
std::cout << elem;
}
std::for_each requires (as the error tries to tell you) an iterator where to start looping and an iterator where to end. You however are passing an iterator and an int, which are "conflicting types". If you want to loop over an whole vector do something like that:
std::vector<int> v{1, 2, 3};
std::for_each(v.begin(), // start at the front
v.end(), // loop over each element
[&] (int& i) {
i++;
});
If you just need to loop over a part of the vector do that
std::vector<int> v{1, 2, 3};
std::for_each(v.begin(), // start at the front
v.begin() + 2, // loop over the first two elements
[&] (int& i) {
i++;
});
You are not using the for_each function correctly. C++ does not know the signature you are using. Please refer to the documentation, e.g. for_each.
The compiler says exactly that. The second parameter of the for_each you are calling is of type int&, but the signature is for_each(InputIterator, InputIterator, Function) and not for_each(InputIterator, int&, Function), so it fails to compile.
Consider the following code:
#include <unordered_map>
#include <tuple>
namespace Test
{
template<typename State>
struct StateTableEntry
{
State state;
};
template<typename State>
using StateRow = std::unordered_map<int,StateTableEntry<State>>;
template<typename StateRowValueType>
auto& entryBAD(StateRowValueType& row)
{ return row.second; }
template<typename StateRowValueType>
auto entryOK(StateRowValueType& row) -> decltype((row.second))
{ return row.second; }
}
template<class T,int I,class O> std::enable_if_t<I==std::tuple_size<T>::value>
for_each_index_of(O&){}
template<class Tuple, int startingIndex=0, class Operation>
std::enable_if_t<startingIndex<std::tuple_size<Tuple>::value>
for_each_index_of(const Operation& operation)
{
operation(std::integral_constant<std::size_t,startingIndex>());
for_each_index_of<Tuple,startingIndex+1>(operation);
}
int main()
{
for_each_index_of<std::tuple<int>>([](const auto&)
{
Test::StateRow<long> stateRow;
for(auto& rowElement : stateRow)
{
auto& state(entryBAD(rowElement).state);
state=1;
}
});
}
If I try to compile it as is, gcc tells me
test.cpp: In instantiation of ‘main()::<lambda(const auto:1&)> [with auto:1 = std::integral_constant<long unsigned int, 0ul>]’:
test.cpp:29:14: required from ‘std::enable_if_t<(startingIndex < std::tuple_size<_Tp>::value)> for_each_index_of(const Operation&) [with Tuple = std::tuple<int>; int startingIndex = 0; Operation = main()::<lambda(const auto:1&)>; std::enable_if_t<(startingIndex < std::tuple_size<_Tp>::value)> = void]’
test.cpp:43:6: required from here
test.cpp:40:44: error: use of ‘template<class StateRowValueType> auto& Test::entryBAD(StateRowValueType&)’ before deduction of ‘auto’
auto& state(entryBAD(rowElement).state);
^
test.cpp:40:44: error: use of ‘auto& Test::entryBAD(StateRowValueType&) [with StateRowValueType = std::pair<const int, Test::StateTableEntry<long int> >]’ before deduction of ‘auto’
test.cpp:24:1: error: ‘std::enable_if_t<(I == std::tuple_size<_Tp>::value)> for_each_index_of(O&) [with T = std::tuple<int>; int I = 1; O = const main()::<lambda(const auto:1&)>; std::enable_if_t<(I == std::tuple_size<_Tp>::value)> = void]’, declared using local type ‘const main()::<lambda(const auto:1&)>’, is used but never defined [-fpermissive]
for_each_index_of(O&){}
^
But if I move the conde of lambda out of the lambda or replace call of entryBAD with entryOK, for some reason compilation succeeds. Same success if I move definition of entryBAD out of namespace Test.
Also, clang++ 3.6 compiles in all cases without complaints.
Is gcc right or is it a bug in it? If gcc is right, then what's wrong with the code?