When I run "upper_bound" with a comparator it gives me this error: error: reference to type 'const std::vector<int, std::allocator>' could not bind to an lvalue of type 'const int. Anyone know the issue?
static bool compareInterval(const vector<int>& a, const vector<int>& b) {
return (a[0] < b[0]);
}
vector<int> corpFlightBookings(vector<vector<int>>& bookings, int n) {
vector<int> ret(n, 0);
sort(bookings.begin(), bookings.end(), compareInterval);
for (int i = 0; i < n; ++i) {
auto low=upper_bound(bookings.begin(), bookings.end(), i, compareInterval);
}
return ret;
}
In file included from prog_joined.cpp:1: In file included from
./precompiled/headers.h:13: In file included from
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/cmath:1927:
In file included from
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/specfun.h:45:
In file included from
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algobase.h:71:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/predefined_ops.h:215:24:
error: reference to type 'const std::vector<int, std::allocator>'
could not bind to an lvalue of type 'const int'
{ return bool(_M_comp(__val, __it)); }
^~~~~ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:2051:8:
note: in instantiation of function template specialization
'__gnu_cxx::__ops::_Val_comp_iter<bool ()(const std::vector<int,
std::allocator> &, const std::vector<int, std::allocator>
&)>::operator()<const int,
__gnu_cxx::__normal_iterator<std::vector<int, std::allocator> *, std::vector<std::vector<int, std::allocator>,
std::allocator<std::vector<int, std::allocator>>>>>' requested
here
if (__comp(__val, __middle))
^ /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_algo.h:2116:19:
note: in instantiation of function template specialization
'std::__upper_bound<__gnu_cxx::__normal_iterator<std::vector<int,
std::allocator> , std::vector<std::vector<int,
std::allocator>, std::allocator<std::vector<int,
std::allocator>>>>, int, __gnu_cxx::__ops::_Val_comp_iter<bool
()(const std::vector<int, std::allocator> &, const
std::vector<int, std::allocator> &)>>' requested here
return std::__upper_bound(__first, __last, __val,
^ Line 12: Char 22: note: in instantiation of function template specialization
'std::upper_bound<__gnu_cxx::__normal_iterator<std::vector<int,
std::allocator> , std::vector<std::vector<int,
std::allocator>, std::allocator<std::vector<int,
std::allocator>>>>, int, bool ()(const std::vector<int,
std::allocator> &, const std::vector<int, std::allocator>
&)>' requested here
auto low=upper_bound(bookings.begin(), bookings.end(), i, compareInterval);
^ 1 error generated.
It turns out "i" needs to be wrapped up to become the same type as an element of bookings
Related
Why doesn't this work?
#include <map>
#include <memory>
void deleter(int* i) {
delete i;
}
std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;
void foo(int* i) {
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);
}
Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/map:61:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_map.h:63:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1668:9: error: no matching constructor for initialization of 'std::unique_ptr<int, void (*)(int *)>'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1655:9: note: in instantiation of function template specialization 'std::pair<const int, std::unique_ptr<int, void (*)(int *)> >::pair<int &&, 0>' requested here
: pair(__first, __second,
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/ext/new_allocator.h:136:23: note: in instantiation of function template specialization 'std::pair<const int, std::unique_ptr<int, void (*)(int *)> >::pair<int &&>' requested here
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/alloc_traits.h:475:8: note: in instantiation of function template specialization '__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::construct<std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
{ __a.construct(__p, std::forward<_Args>(__args)...); }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:637:23: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > > >::construct<std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_Alloc_traits::construct(_M_get_Node_allocator(),
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:654:4: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_construct_node<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_M_construct_node(__tmp, std::forward<_Args>(__args)...);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:2414:19: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_create_node<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_map.h:518:15: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_emplace_hint_unique<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
__i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
^
<source>:11:6: note: in instantiation of member function 'std::map<int, std::unique_ptr<int, void (*)(int *)>, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::operator[]' requested here
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:191:12: note: candidate template ignored: substitution failure [with _Up = void (*)(int *)]: no type named 'type' in 'std::enable_if<false, void>'
constexpr unique_ptr() noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:204:2: note: candidate constructor template not viable: requires single argument '__p', but no arguments were provided
unique_ptr(pointer __p) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:236:12: note: candidate constructor template not viable: requires 1 argument, but 0 were provided
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:255:2: note: candidate constructor template not viable: requires single argument '__u', but no arguments were provided
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:265:2: note: candidate constructor template not viable: requires single argument '__u', but no arguments were provided
unique_ptr(auto_ptr<_Up>&& __u) noexcept;
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:241:7: note: candidate constructor not viable: requires single argument '__u', but no arguments were provided
unique_ptr(unique_ptr&& __u) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:394:7: note: candidate constructor not viable: requires 1 argument, but 0 were provided
unique_ptr(const unique_ptr&) = delete;
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:215:7: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
unique_ptr(pointer __p,
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:227:7: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
unique_ptr(pointer __p,
^
1 error generated.
Compiler returned: 1
The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.
Fix:
struct Deleter {
void operator()(int* i) { delete i; }
};
std::map<int, std::unique_ptr<int, Deleter>> m;
void foo(int* i) {
m[0] = std::unique_ptr<int, Deleter>(i);
}
This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).
std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator[] requires that the value type of the map be default constructable. That means as is you cannot use operator [] with this type of map.
In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.
I'm trying to compile the following code, but on the line threads[i] = std::thread(find_elements[i], block_start, block_end, match); the std::thread object cannot be constructed with given arguments.
#include <iostream>
#include <thread>
#include <vector>
#include <future>
class join_threads
{
public:
explicit join_threads(std::vector<std::thread>& threads)
: threads_(threads) {}
~join_threads()
{
for (size_t i = 0; i < threads_.size(); ++i)
{
if(threads_[i].joinable())
{
threads_[i].join();
}
}
}
private:
std::vector<std::thread>& threads_;
};
template <typename Iterator, typename MatchType>
Iterator parallel_find(Iterator first, Iterator last, MatchType match)
{
class find_element
{
public:
void operator()(Iterator begin, Iterator end, MatchType match)
{
try
{
while (begin != end)
{
if (*begin == match)
{
result_.set_value(begin);
is_found_ = true;
return;
}
++begin;
}
result_.set_value(end);
}
catch(...)
{
result_.set_exception(std::current_exception());
}
}
Iterator get() { return result_.get_future().get(); }
bool is_found() const { return is_found_; }
private:
std::promise<Iterator> result_;
bool is_found_ = false;
};
const unsigned length = std::distance(first, last);
if (0 == length) return last;
const unsigned min_per_thread = 25;
const unsigned max_threads = (length + min_per_thread - 1) / min_per_thread;
const unsigned hardware_threads = std::thread::hardware_concurrency();
const unsigned num_threads = std::min(
hardware_threads != 0 ? hardware_threads : 2, max_threads);
const unsigned block_size = length / num_threads;
std::vector<std::thread> threads(num_threads - 1);
std::vector<find_element> find_elements(num_threads);
{
join_threads joiner(threads);
Iterator block_start = first;
for (unsigned i = 0; i < num_threads - 1; ++i)
{
Iterator block_end = block_start;
std::advance(block_end, block_size);
threads[i] = std::thread(find_elements[i], block_start, block_end, match);
block_start = block_end;
}
find_elements[num_threads - 1](block_start, last, match);
}
for (unsigned i = 0; i < num_threads - 1; ++i)
{
if (find_elements[i].is_found())
{
return find_elements[i].get();
}
}
return find_elements[num_threads - 1].get();
}
int main()
{
std::vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8 };
parallel_find(v.begin(), v.end(), 9);
return 0;
}
The exact error produced by clang++ version 3.9.1 is the following:
In file included from ../../../sources/test/main.cpp:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/thread:39:
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/functional:1379:11: error: no matching constructor for initialization of 'std::tuple<find_element, __normal_iterator<int *, vector<int, allocator<int> > >, __normal_iterator<int *, vector<int, allocator<int> > >, int>'
: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...)
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/functional:1426:14: note: in instantiation of function template specialization 'std::_Bind_simple<find_element (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, int)>::_Bind_simple<const find_element &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>' requested here
return __result_type(
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/thread:137:13: note: in instantiation of function template specialization 'std::__bind_simple<find_element &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>' requested here
std::__bind_simple(std::forward<_Callable>(__f),
^
../../../sources/test/main.cpp:84:20: note: in instantiation of function template specialization 'std::thread::thread<find_element &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>' requested here
threads[i] = std::thread(find_elements[i], block_start, block_end, match);
^
../../../sources/test/main.cpp:105:3: note: in instantiation of function template specialization 'parallel_find<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, int>' requested here
parallel_find(v.begin(), v.end(), 9);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:600:18: note: candidate template ignored: disabled by 'enable_if' [with _Dummy = void]
_TCC<_Dummy>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:611:18: note: candidate template ignored: disabled by 'enable_if' [with _Dummy = void]
_TCC<_Dummy>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:628:5: note: candidate template ignored: disabled by 'enable_if' [with _UElements = <const find_element &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>]
_TC<sizeof...(_UElements) == 1, _Elements...>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:641:5: note: candidate template ignored: disabled by 'enable_if' [with _UElements = <const find_element &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>]
_TC<sizeof...(_UElements) == 1, _Elements...>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:737:19: note: candidate template ignored: disabled by 'enable_if' [with _Alloc = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _UElements = <__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>]
enable_if<_TMC<_UElements...>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:748:19: note: candidate template ignored: disabled by 'enable_if' [with _Alloc = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _UElements = <__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &, int &>]
enable_if<_TMC<_UElements...>::template
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:579:17: note: candidate constructor template not viable: requires 0 arguments, but 4 were provided
constexpr tuple()
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:589:26: note: candidate constructor template not viable: requires 0 arguments, but 4 were provided
explicit constexpr tuple()
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:670:19: note: candidate constructor template not viable: requires single argument '__in', but 4 arguments were provided
constexpr tuple(const tuple<_UElements...>& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:682:28: note: candidate constructor template not viable: requires single argument '__in', but 4 arguments were provided
explicit constexpr tuple(const tuple<_UElements...>& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:694:19: note: candidate constructor template not viable: requires single argument '__in', but 4 arguments were provided
constexpr tuple(tuple<_UElements...>&& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:705:28: note: candidate constructor template not viable: requires single argument '__in', but 4 arguments were provided
explicit constexpr tuple(tuple<_UElements...>&& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:721:2: note: candidate constructor template not viable: requires 6 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:732:11: note: candidate constructor template not viable: requires 6 arguments, but 4 were provided
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:711:2: note: candidate constructor template not viable: requires 2 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:759:2: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:763:2: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:772:2: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:784:11: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:796:2: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:808:11: note: candidate constructor template not viable: requires 3 arguments, but 4 were provided
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:654:17: note: candidate constructor not viable: requires 1 argument, but 4 were provided
constexpr tuple(tuple&&) = default;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/6.2.0/../../../../include/c++/6.2.0/tuple:652:17: note: candidate constructor not viable: requires 1 argument, but 4 were provided
constexpr tuple(const tuple&) = default;
^
1 error generated.
make: *** [main.o] Error 1
I am currently trying to implement a class with a vector of stacks. The class shall work as a stack to other objects but distribute the data to different stacks of a maximum size internally. If a stack is full a new one is created and pushed to the internal vector.
My current approach generates errors:
prog.cpp: In instantiation of ‘SetOfStack<T>::SetOfStack(int) [with T = int]’:
prog.cpp:54:32: required from here
prog.cpp:13:17: error: no matching function for call to ‘std::vector<std::stack<int, std::deque<int, std::allocator<int> > >, std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::push_back(std::stack<int, std::deque<int, std::allocator<int> > >*)’
stacks.push_back( new stack<T> );
^
/usr/include/c++/4.8/bits/stl_vector.h:901:7: note: no known conversion for argument 1 from ‘std::stack<int, std::deque<int, std::allocator<int> > >*’ to ‘const value_type& {aka const std::stack<int, std::deque<int, std::allocator<int> > >&}’
/usr/include/c++/4.8/bits/stl_vector.h:919:7: note: void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::stack<int, std::deque<int, std::allocator<int> > >; _Alloc = std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > >; std::vector<_Tp, _Alloc>::value_type = std::stack<int, std::deque<int, std::allocator<int> > >]
push_back(value_type&& __x)
^
/usr/include/c++/4.8/bits/stl_vector.h:919:7: note: no known conversion for argument 1 from ‘std::stack<int, std::deque<int, std::allocator<int> > >*’ to ‘std::vector<std::stack<int, std::deque<int, std::allocator<int> > >, std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type&& {aka std::stack<int, std::deque<int, std::allocator<int> > >&&}’
prog.cpp: In instantiation of ‘void SetOfStack<T>::push(T) [with T = int]’:
prog.cpp:55:21: required from here
prog.cpp:22:25: error: ‘__gnu_cxx::__alloc_traits<std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type’ has no member named ‘push_back’
stacks[current_stack].push_back(new stack<T>);
^
prog.cpp: In instantiation of ‘T SetOfStack<T>::pop() [with T = int]’:
prog.cpp:56:27: required from here
prog.cpp:34:25: error: ‘__gnu_cxx::__alloc_traits<std::allocator<std::stack<int, std::deque<int, std::allocator<int> > > > >::value_type’ has no member named ‘pop_back’
stacks[current_stack].pop_back();
^
Sample Code:
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
template <class T>
class SetOfStack {
public:
SetOfStack( int max_size ): current_stack(0), max_stack_size(max_size) {
stacks.reserve(10);
stacks.push_back( new stack<T> );
}
~SetOfStack() {
stacks.clear();
}
void push( T value ) {
stacks[current_stack].push(value);
if(stacks[current_stack].size() > max_stack_size) {
stacks[current_stack].push_back(new stack<T>);
current_stack++;
if(current_stack % 10 == 0 && current_stack > stacks.size()) {
stacks.reserve(stacks.size() + 10);
}
}
}
T pop() {
T value = stacks[current_stack].top();
stacks[current_stack].pop();
if(stacks[current_stack].size() == 0 && current_stack != 0 ) {
stacks[current_stack].pop_back();
current_stack--;
}
}
T popAt( int index ) {
T value = stacks[index].top();
stacks[index].pop();
}
private:
int current_stack;
int max_stack_size;
vector< stack<T> > stacks;
};
int main() {
// Test code
SetOfStack<int> s_o_s(3);
s_o_s.push(1);
cout << s_o_s.pop() << endl;
return 0;
}
The error you're getting is this line:
stacks.push_back( new stack<T> );
As well as this line:
stacks[current_stack].push_back(new stack<T>);
Because you have declared stacks as a non-pointer:
vector< stack<T> > stacks;
So you want to use just stack<T>() instead of new stack<T>
Additionally, std::stack does not have a function push_back, you need to use push instead.
stacks.push_back(stack<T>());
stacks[current_stack].push(value);
As well as pop and not pop_back():
stacks[current_stack].pop();
At which point, you no longer need the deletes I mentioned in my original comment, since it looks like you were not intending to call new
I was looking at the example for std::async here, as follows:
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <future>
template <typename RAIter>
int parallel_sum(RAIter beg, RAIter end)
{
auto len = std::distance(beg, end);
if(len < 1000)
return std::accumulate(beg, end, 0);
RAIter mid = beg + len/2;
auto handle = std::async(std::launch::async,
parallel_sum<RAIter>, mid, end);
int sum = parallel_sum(beg, mid);
return sum + handle.get();
}
int main()
{
std::vector<int> v(10000, 1);
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
}
I tried compiling it with the web compiler for Clang 3.4 and it resulted in the output The sum is instead of the expected The sum is 1000.
I copied the example and compiled with clang 3.5-1ubuntu1 / gcc 4.8 on Ubuntu 14.04.1 64-bit using the following command:
clang++ -g main.cpp -std=c++1y -o out -pthread;
I get the following error:
main.cpp:15:19: error: no matching function for call to 'async'
auto handle = std::async(std::launch::async,
^~~~~~~~~~
main.cpp:24:35: note: in instantiation of function template specialization
'parallel_sum<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> >
> >' requested here
std::cout << "The sum is " << parallel_sum(v.begin(), v.end()) << '\n';
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/future:1523:5: note:
candidate template ignored: substitution failure [with _Fn = int
(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >), _Args =
<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &>]:
function cannot return function type 'int (__gnu_cxx::__normal_iterator<int *,
std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<int *,
std::vector<int, std::allocator<int> > >)'
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/future:1543:5: note:
candidate template ignored: substitution failure [with _Fn = std::launch, _Args = <int
(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >),
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &>]: no
type named 'type' in 'std::result_of<std::launch (int
(*)(__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >),
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &,
__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > &)>'
async(_Fn&& __fn, _Args&&... __args)
^
1 error generated.
make: *** [all] Error 1
Is this a bug in clang, gcc, libstdc++, or am I missing something?
I think this is a bug in clang++. Unless there's a strange restricted rule that I'm not aware of, an id-expression referring to a function is an lvalue. However, clang++ makes a distinction between function template specializations and ordinary functions in the deduction for a universal reference:
#include <iostream>
template<class T>
void print_type()
{
std::cout << __PRETTY_FUNCTION__ << "\n";
}
template <class T>
int foo(bool) { return 42; }
int bar(bool) { return 42; }
template<class T>
void deduce(T&&)
{
print_type<T>();
}
int main()
{
deduce(foo<bool>);
deduce(bar);
}
Output, clang++ up to and including an early 3.5:
void print_type() [T = int (bool)]
void print_type() [T = int (&)(bool)]
Live example
std::result_of is used in libstdc++'s implementation of std::async to get the return type of the function (snippet from here):
template<typename _Fn, typename... _Args>
future<typename result_of<_Fn(_Args...)>::type>
async(launch __policy, _Fn&& __fn, _Args&&... __args)
If we pass foo<bool> as the second argument, clang++ deduces _Fn == int (bool).
The type of the function (object) is combined with the argument types for result_of. This is probably a relict of C++03, where we didn't have variadic templates yet. The argument types are passed to allow result_of to resolve overloaded functions like an overloaded operator() in case _Fn is a class type.
However, if _Fn is deduced not to a function reference, but to a function type, the combination _Fn(_Args...) forms an illegal type: a function returning a function:
_Fn == int(bool)
_Args... == bool
==> _Fn(_Args...) == int(bool)(bool)
But there's more to it: The above declaration of async is defective, see LWG 2021. Howard Hinnant changed the declaration in libc++ to:
template <class F, class... Args>
future < typename result_of<
typename decay<F>::type(typename decay<Args>::type...)
>::type
>
async(launch policy, F&& f, Args&&... args);
so libc++ decays the function to a function pointer. The problem caused by the missing lvalue reference disappears.
It seems the following code doesn't compile under clang (llvm version 5.0):
#include <functional>
int main()
{
int i;
std::function<void(int&)> f;
std::function<void()> f2 = std::bind(f, std::ref(i));
}
If f is declared as follows (i.e., not a std::function), then it compiles fine:
void f(int& n1);
Am I doing something wrong or is this really a compiler bug?
This is the compiler error I am getting:
In file included from test.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:465:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:599:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/tuple:234:73: error: no matching constructor for initialization of 'std::__1::reference_wrapper<int>'
_NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/tuple:447:23: note: in instantiation of member function 'std::__1::__tuple_leaf<0, std::__1::reference_wrapper<int>, false>::__tuple_leaf' requested here
_LIBCPP_CONSTEXPR __tuple_impl()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/tuple:550:23: note: in instantiation of member function 'std::__1::__tuple_impl<std::__1::__tuple_indices<0>, std::__1::reference_wrapper<int> >::__tuple_impl' requested
here
_LIBCPP_CONSTEXPR tuple()
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1744:11: note: in instantiation of member function 'std::__1::tuple<std::__1::reference_wrapper<int> >::tuple' requested here
__bound_args_(_VSTD::forward<_BA>(__bound_args)...) {}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:2243:15: note: in instantiation of function template specialization 'std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int>
>::__bind<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> >, , void>' requested here
__first_(_VSTD::forward<_Args1>(get<_I1>(__first_args))...)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/memory:2421:15: note: in instantiation of function template specialization 'std::__1::__libcpp_compressed_pair_imp<std::__1::__bind<std::__1::function<void (int &)> &,
std::__1::reference_wrapper<int> >, std::__1::allocator<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> > >, 2>::__libcpp_compressed_pair_imp<std::__1::__bind<std::__1::function<void (int &)> &,
std::__1::reference_wrapper<int> > &&, , 0, >' requested here
: base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:992:11: note: in instantiation of function template specialization 'std::__1::__compressed_pair<std::__1::__bind<std::__1::function<void (int &)> &,
std::__1::reference_wrapper<int> >, std::__1::allocator<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> > > >::__compressed_pair<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> > &&, >'
requested here
: __f_(piecewise_construct, _VSTD::forward_as_tuple(_VSTD::move(__f)),
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/functional:1277:26: note: in instantiation of member function 'std::__1::__function::__func<std::__1::__bind<std::__1::function<void (int &)> &,
std::__1::reference_wrapper<int> >, std::__1::allocator<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> > >, void ()>::__func' requested here
::new (__f_) _FF(_VSTD::move(__f));
^
test.cpp:7:29: note: in instantiation of function template specialization 'std::__1::function<void ()>::function<std::__1::__bind<std::__1::function<void (int &)> &, std::__1::reference_wrapper<int> > >' requested here
std::function<void()> f2 = std::bind(f, std::ref(i));
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__functional_base:365:31: note: candidate constructor not viable: requires single argument '__f', but no arguments were provided
_LIBCPP_INLINE_VISIBILITY reference_wrapper(type& __f) _NOEXCEPT : __f_(&__f) {}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__functional_base:367:14: note: candidate constructor not viable: requires 1 argument, but 0 were provided
private: reference_wrapper(type&&); public: // = delete; // do not bind to temps
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__functional_base:354:24: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class _LIBCPP_TYPE_VIS reference_wrapper
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__functional_base:354:24: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
1 error generated.
The bug is fixed in version 5.1