Why STL requires a temporary iterator variable to compile this? - c++

Here is a very straightforward piece of code:
#include <vector>
int main() {
std::vector<int> myVec(5);
std::vector<int>::const_iterator first = myVec.begin();
std::vector<int>::const_iterator last = myVec.begin() + 3;
std::vector<int> newVec1(first, last);
std::vector<int> newVec2(myVec.begin(), last);
return 0;
}
Line declaring newVec1 compiles.
Line declaring newVec2 fails with following error:
prog.cpp: In function 'int main()':
prog.cpp:11:49: error: no matching function for call to 'std::vector<int>::vector(std::vector<int>::iterator, std::vector<int>::const_iterator&)'
std::vector<int> newVec2(myVec.begin(), last);
^
prog.cpp:11:49: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
from prog.cpp:3:
/usr/include/c++/4.9/bits/stl_vector.h:401:9: note: template<class _InputIterator, class> std::vector<_Tp, _Alloc>::vector(_InputIterator, _InputIterator, const allocator_type&)
vector(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/4.9/bits/stl_vector.h:401:9: note: template argument deduction/substitution failed:
prog.cpp:11:49: note: deduced conflicting types for parameter '_InputIterator' ('__gnu_cxx::__normal_iterator<int*, std::vector<int> >' and '__gnu_cxx::__normal_iterator<const int*, std::vector<int> >')
std::vector<int> newVec2(myVec.begin(), last);
^
In file included from /usr/include/c++/4.9/vector:64:0,
from prog.cpp:3:
/usr/include/c++/4.9/bits/stl_vector.h:373:7: note: std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(initializer_list<value_type> __l,
^
/usr/include/c++/4.9/bits/stl_vector.h:373:7: note: no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::initializer_list<int>'
/usr/include/c++/4.9/bits/stl_vector.h:348:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(vector&& __rv, const allocator_type& __m)
^
/usr/include/c++/4.9/bits/stl_vector.h:348:7: note: no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>&&'
/usr/include/c++/4.9/bits/stl_vector.h:339:7: note: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(const vector& __x, const allocator_type& __a)
^
/usr/include/c++/4.9/bits/stl_vector.h:339:7: note: no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'const std::vector<int>&'
/usr/include/c++/4.9/bits/stl_vector.h:335:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>&&) [with _Tp = int; _Alloc = std::allocator<int>]
vector(vector&& __x) noexcept
^
/usr/include/c++/4.9/bits/stl_vector.h:335:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:318:7: note: std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = int; _Alloc = std::allocator<int>]
vector(const vector& __x)
^
/usr/include/c++/4.9/bits/stl_vector.h:318:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:289:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::value_type = int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(size_type __n, const value_type& __value,
^
/usr/include/c++/4.9/bits/stl_vector.h:289:7: note: no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>::size_type {aka unsigned int}'
/usr/include/c++/4.9/bits/stl_vector.h:277:7: note: std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::size_type = unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(size_type __n, const allocator_type& __a = allocator_type())
^
/usr/include/c++/4.9/bits/stl_vector.h:277:7: note: no known conversion for argument 1 from 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'std::vector<int>::size_type {aka unsigned int}'
/usr/include/c++/4.9/bits/stl_vector.h:264:7: note: std::vector<_Tp, _Alloc>::vector(const allocator_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<int>]
vector(const allocator_type& __a) _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.9/bits/stl_vector.h:264:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_vector.h:253:7: note: std::vector<_Tp, _Alloc>::vector() [with _Tp = int; _Alloc = std::allocator<int>]
vector()
^
/usr/include/c++/4.9/bits/stl_vector.h:253:7: note: candidate expects 0 arguments, 2 provided
Both g++ and Visual Studio fail to compile this, any idea why?
myVec.begin() is the same as first...

myVec.begin() is not the same as first. first is of type std::vector<int>::const_iterator, whereas myVec.begin() is of type std::vector<int>::iterator.
If you want a const iterator, use cbegin:
std::vector<int> newVec2(myVec.cbegin(), last);

vec.begin() is not the same as first because it will return you an iterator, not a const_iterator.
This happens because having a const or non-const iterator depends on the type of the access you have to the container, not on the use you wish to do with the iterator and it's also the reason for which for example creating proxies is the only way to separate read from write operations in array-like objects ::operator[] instead of just rely on const or non-const version.
It's just of the many cases in which the const-correctness concept shows its limits.

Related

My file fails to compile due to `insert` and `find` functions of `vector`

I am a beginner in C++ language. When I try to compile a file with g++ I get the following error. I'm pretty sure the errors are all on find and insert. I went online to try and get help, but a lot of people say just #include <algorithm> will do. I did do that, but it still doesn't compile. Below is my code and error message.
Intersection of Two Arrays.cpp:11:22: error: ‘class std::vector<int>’ has no member named ‘find’
11 | if (nums_set.find(num) != nums_set.end()) {
| ^~~~
Intersection of Two Arrays.cpp:12:34: error: no matching function for call to ‘std::vector<int>::insert(int&)’
12 | result_set.insert(num);
| ^
In file included from /usr/include/c++/9/vector:72,
from Intersection of Two Arrays.cpp:2:
/usr/include/c++/9/bits/vector.tcc:130:5: note: candidate: ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*; std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >; typename __gnu_cxx::__alloc_traits<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::const_pointer = const int*; std::vector<_Tp, _Alloc>::value_type = int]’
130 | vector<_Tp, _Alloc>::
| ^~~~~~~~~~~~~~~~~~~
/usr/include/c++/9/bits/vector.tcc:130:5: note: candidate expects 2 arguments, 1 provided
In file included from /usr/include/c++/9/vector:67,
from Intersection of Two Arrays.cpp:2:
/usr/include/c++/9/bits/stl_vector.h:1290:7: note: candidate: ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*; std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >; typename __gnu_cxx::__alloc_traits<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::const_pointer = const int*; std::vector<_Tp, _Alloc>::value_type = int]’
1290 | insert(const_iterator __position, value_type&& __x)
| ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:1290:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/9/bits/stl_vector.h:1307:7: note: candidate: ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, std::initializer_list<_Tp>) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*; std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >; typename __gnu_cxx::__alloc_traits<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::const_pointer = const int*]’
1307 | insert(const_iterator __position, initializer_list<value_type> __l)
| ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:1307:7: note: candidate expects 2 arguments, 1 provided
/usr/include/c++/9/bits/stl_vector.h:1332:7: note: candidate: ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = int; _Alloc = std::allocator<int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int*; std::vector<_Tp, _Alloc>::const_iterator = __gnu_cxx::__normal_iterator<const int*, std::vector<int> >; typename __gnu_cxx::__alloc_traits<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type>::const_pointer = const int*; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = int]’
1332 | insert(const_iterator __position, size_type __n, const value_type& __x)
| ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:1332:7: note: candidate expects 3 arguments, 1 provided
/usr/include/c++/9/bits/stl_vector.h:1376:2: note: candidate: ‘template<class _InputIterator, class> std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::const_iterator, _InputIterator, _InputIterator) [with _InputIterator = _InputIterator; <template-parameter-2-2> = <template-parameter-1-2>; _Tp = int; _Alloc = std::allocator<int>]’
1376 | insert(const_iterator __position, _InputIterator __first,
| ^~~~~~
/usr/include/c++/9/bits/stl_vector.h:1376:2: note: template argument deduction/substitution failed:
Intersection of Two Arrays.cpp:12:34: note: candidate expects 3 arguments, 1 provided
12 | result_set.insert(num);
| ^
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> result_set;
vector<int> nums_set(nums1.begin(), nums1.end());
for (int num : nums2) {
if (nums_set.find(num) != nums_set.end()) {
result_set.insert(num);
}
}
return vector<int>(result_set.begin(), result_set.end());
}
Note: The main function of this equation is to return the elements contained in both vectors.

gcc compile error "binding ‘const s’ to reference of type ‘s&’ discards qualifiers" when using boost::container::static_vector in other container

When using boost::container::static_vector in another container such as std::vector, gcc is returning a compile error. The following test case reproduces the error:
#include <boost/container/static_vector.hpp>
#include <vector>
struct s
{
boost::container::static_vector<int,6> a;
};
int main()
{
std::vector<s> b;
b.resize(6);
}
Complied with g++ template_test2.cpp on Ubuntu Xenial results in the following error:
In file included from /usr/include/c++/5/bits/char_traits.h:39:0,
from /usr/include/c++/5/string:40,
from /usr/include/c++/5/stdexcept:39,
from /usr/include/boost/container/throw_exception.hpp:26,
from /usr/include/boost/container/new_allocator.hpp:24,
from /usr/include/boost/container/vector.hpp:28,
from /usr/include/boost/container/static_vector.hpp:25,
from template_test2.cpp:1:
/usr/include/c++/5/bits/stl_algobase.h: In instantiation of ‘typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), void>::__type std::__fill_a(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = s*; _Tp = s; typename __gnu_cxx::__enable_if<(! std::__is_scalar<_Tp>::__value), void>::__type = void]’:
/usr/include/c++/5/bits/stl_algobase.h:747:20: required from ‘void std::fill(_ForwardIterator, _ForwardIterator, const _Tp&) [with _ForwardIterator = s*; _Tp = s]’
/usr/include/c++/5/bits/vector.tcc:469:14: required from ‘void std::vector<_Tp, _Alloc>::_M_fill_insert(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = s; _Alloc = std::allocator<s>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<s*, std::vector<s> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = s*; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = s]’
/usr/include/c++/5/bits/stl_vector.h:1073:23: required from ‘void std::vector<_Tp, _Alloc>::insert(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = s; _Alloc = std::allocator<s>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<s*, std::vector<s> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = s*; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = s]’
/usr/include/c++/5/bits/stl_vector.h:716:10: required from ‘void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type, std::vector<_Tp, _Alloc>::value_type) [with _Tp = s; _Alloc = std::allocator<s>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = s]’
template_test2.cpp:12:11: required from here
/usr/include/c++/5/bits/stl_algobase.h:701:11: error: binding ‘const s’ to reference of type ‘s&’ discards qualifiers
*__first = __value;
This error only occurs if struct s contains a static vector. What is the cause of this error, and is there a workaround available?
It looks like the default copy assigment operator generated by compiler has signature
s& operator= (s&);
and your code fails in this line of fill algorithm (it is called somehow in resize method):
for (; __first != __last; ++__first)
*__first = __value; // <----- call operator=(s&) passing const s& object
because __value is const reference to s object and it cannot be passed as argument to
operator=(s&) (const object cannot be modified).
About generating default copy assignment operator for classes you can read here. There is something strange with implementation of static_vector that default copy assignment operator takes s& as argument instead of const s&.
To resolve this issue you can implement your own version of this operator:
s& operator = (const s& other) {
a = other.a;
return *this;
}

Signature of Generated operator=()?

I have the following code:
#include <string>
#include <vector>
struct S {
const std::string str;
};
int main() {
std::vector<S> v;
const std::string test("test");
S s;
v.push_back(s);
}
It compiles fine with g++ 4.8.5:
$ g++ --version
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
But when I tried to compile it with g++ 4.6.2, I got the following errors:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0,
from compilerTest.cpp:2:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const S&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::value_type = S]’
compilerTest.cpp:12:14: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: use of deleted function ‘S& S::operator=(const S&)’
compilerTest.cpp:4:8: error: ‘S& S::operator=(const S&)’ is implicitly deleted because the default definition would be ill-formed:
compilerTest.cpp:4:8: error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’ discards qualifiers [-fpermissive]
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/char_traits.h:41:0,
from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:42,
from compilerTest.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const S&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::value_type = S]’
compilerTest.cpp:12:14: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function ‘S& S::operator=(const S&)’
Why S& S::operator=(const S&) is "deleted"?
I was using the command to compile:
g++ -Wall compilerTest.cpp -o compilerTest -std=c++0x
Even I uses emplace_back(), it gives me similar error:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/x86_64-redhat-linux/bits/c++allocator.h:34:0,
from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/allocator.h:48,
from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:43,
from compilerTest.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, __gnu_cxx::new_allocator<_Tp>::pointer = S*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:97:6: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’
compilerTest.cpp:11:18: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h:114:4: error: no matching function for call to ‘S::S(std::basic_string<char>&)’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h:114:4: note: candidates are:
compilerTest.cpp:4:8: note: S::S()
compilerTest.cpp:4:8: note: candidate expects 0 arguments, 1 provided
compilerTest.cpp:4:8: note: S::S(const S&)
compilerTest.cpp:4:8: note: no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const S&’
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0,
from compilerTest.cpp:2:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’
compilerTest.cpp:11:18: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: no matching function for call to ‘S::S(std::basic_string<char>&)’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: note: candidates are:
compilerTest.cpp:4:8: note: S::S()
compilerTest.cpp:4:8: note: candidate expects 0 arguments, 1 provided
compilerTest.cpp:4:8: note: S::S(const S&)
compilerTest.cpp:4:8: note: no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const S&’
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/char_traits.h:41:0,
from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:42,
from compilerTest.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’
compilerTest.cpp:11:18: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function ‘S& S::operator=(const S&)’
compilerTest.cpp:4:8: error: ‘S& S::operator=(const S&)’ is implicitly deleted because the default definition would be ill-formed:
compilerTest.cpp:4:8: error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’ discards qualifiers [-fpermissive]
Why S& S::operator=(const S&) is "deleted"?
Because S has a const member str which makes the defaulted copy assignment operator is defined as deleted.
A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:
T has a non-static data member or a direct or virtual base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);
It's impossible to call operator= on a const string, it's a non-const member function.
And the type requirements of std::vector changed from C++11:
T must meet the requirements of CopyAssignable and CopyConstructible.
(until C++11)
The requirements that are imposed on the elements depend on the actual
operations performed on the container. Generally, it is required that
element type is a complete type and meets the requirements of
Erasable, but many member functions impose stricter requirements.
(since C++11)
So from C++11 the requirment depends on the operation you performed. In fact, std::vector::push_back doesn't need type T to be CopyAssignable, CopyInsertable would be fine.
Type requirements
- T must meet the requirements of CopyInsertable in order to use overload (1).
That's why it compiles with gcc4.8.5, but gcc4.6.2 complains the copy assignment operator is deleted. (AFAIK gcc supported C++11 from 4.8.1)
Copy assignment is implicitly deleted when you have a non static const member
That's because the object that you copy into is not re-initialized, so you have an existing const that you can't reassign into.
In your case there's not full support of C++11, which requires vector members to have copy assignment

Why can I not call reserve on a vector of const elements? [duplicate]

This question already has answers here:
Why does stack<const string> not compile in g++? [duplicate]
(2 answers)
Closed 9 years ago.
I have been told that it is good practice to call vector.reserve() before inserting a large amount of elements. I just came upon a situation where I want to put a large number of const elements into a vector. When calling reserve(), however, a compiler error is thrown.
Consider the following code reproducing the problem:
#include <vector>
int main()
{
std::vector<const int> vec;
vec.reserve(2);
}
This results in the following huge compiler error:
In file included from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h:33:0,
from /usr/include/c++/4.8/bits/allocator.h:46,
from /usr/include/c++/4.8/vector:61,
from vecreserve.cpp:1:
/usr/include/c++/4.8/ext/new_allocator.h: In instantiation of ‘struct __gnu_cxx::new_allocator’:
/usr/include/c++/4.8/bits/allocator.h:92:11: required from ‘class std::allocator’
/usr/include/c++/4.8/bits/alloc_traits.h:90:43: required from ‘struct std::allocator_traits >’
/usr/include/c++/4.8/ext/alloc_traits.h:121:10: required from ‘struct __gnu_cxx::__alloc_traits >’
/usr/include/c++/4.8/bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base >’
/usr/include/c++/4.8/bits/stl_vector.h:210:11: required from ‘class std::vector’
vecreserve.cpp:5:26: required from here
/usr/include/c++/4.8/ext/new_allocator.h:93:7: error: ‘const _Tp* __gnu_cxx::new_allocator::address(__gnu_cxx::new_allocator::const_reference) const [with _Tp = const int; __gnu_cxx::new_allocator::const_pointer = const int*; __gnu_cxx::new_allocator::const_reference = const int&]’ cannot be overloaded
address(const_reference __x) const _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.8/ext/new_allocator.h:89:7: error: with ‘_Tp* __gnu_cxx::new_allocator::address(__gnu_cxx::new_allocator::reference) const [with _Tp = const int; __gnu_cxx::new_allocator::pointer = const int*; __gnu_cxx::new_allocator::reference = const int&]’
address(reference __x) const _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.8/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator::deallocate(__gnu_cxx::new_allocator::pointer, __gnu_cxx::new_allocator::size_type) [with _Tp = const int; __gnu_cxx::new_allocator::pointer = const int*; __gnu_cxx::new_allocator::size_type = long unsigned int]’:
/usr/include/c++/4.8/bits/stl_vector.h:174:4: required from ‘void std::_Vector_base::_M_deallocate(std::_Vector_base::pointer, std::size_t) [with _Tp = const int; _Alloc = std::allocator; std::_Vector_base::pointer = const int*; std::size_t = long unsigned int]’
/usr/include/c++/4.8/bits/vector.tcc:80:28: required from ‘void std::vector::reserve(std::vector::size_type) [with _Tp = const int; _Alloc = std::allocator; std::vector::size_type = long unsigned int]’
vecreserve.cpp:6:16: required from here
/usr/include/c++/4.8/ext/new_allocator.h:110:30: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
{ ::operator delete(__p); }
^
In file included from /usr/include/c++/4.8/ext/new_allocator.h:33:0,
from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h:33,
from /usr/include/c++/4.8/bits/allocator.h:46,
from /usr/include/c++/4.8/vector:61,
from vecreserve.cpp:1:
/usr/include/c++/4.8/new:95:6: error: initializing argument 1 of ‘void operator delete(void*)’ [-fpermissive]
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
^
In file included from /usr/include/c++/4.8/vector:60:0,
from vecreserve.cpp:1:
/usr/include/c++/4.8/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = true; _II = const int*; _OI = const int*]’:
/usr/include/c++/4.8/bits/stl_algobase.h:428:38: required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = true; _II = const int*; _OI = const int*]’
/usr/include/c++/4.8/bits/stl_algobase.h:460:17: required from ‘_OI std::copy(_II, _II, _OI) [with _II = std::move_iterator; _OI = const int*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:93:53: required from ‘static _ForwardIterator std::__uninitialized_copy::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = const int*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:117:41: required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = const int*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator&) [with _InputIterator = std::move_iterator; _ForwardIterator = const int*; _Tp = const int]’
/usr/include/c++/4.8/bits/stl_vector.h:1142:29: required from ‘std::vector::pointer std::vector::_M_allocate_and_copy(std::vector::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator; _Tp = const int; _Alloc = std::allocator; std::vector::pointer = const int*; std::vector::size_type = long unsigned int]’
/usr/include/c++/4.8/bits/vector.tcc:75:70: required from ‘void std::vector::reserve(std::vector::size_type) [with _Tp = const int; _Alloc = std::allocator; std::vector::size_type = long unsigned int]’
vecreserve.cpp:6:16: required from here
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: error: no matching function for call to ‘std::__copy_move::__copy_m(const int*&, const int*&, const int*&)’
_Category>::__copy_m(__first, __last, __result);
^
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note: candidate is:
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note: template static _Tp* std::__copy_move::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = true]
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
^
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note: deduced conflicting types for parameter ‘_Tp’ (‘int’ and ‘const int’)
_Category>::__copy_m(__first, __last, __result);
^
Why does this happen? Should I not call reserve on a vector of const elements? If so, why not?
You are violating the requirements for the elements stated by the class vector. An element must be CopyAssignable.
const int is not a valid type to put into any standard container since it is not assignable.

Wierd C++ vector error? In file included from c++/4.7.2/vector:70:0

I am getting something like:
[jiewmeng#JM Assignment 2]$ mpic++ basketball-match.cpp -o basketball-match && mpirun -np 12 basketball-match
In file included from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/vector:70:0,
from basketball-match.cpp:4:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/vector.tcc: In instantiation of ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, const _Tp&) [with _Tp = int [2]; _Alloc = std::allocator<int [2]>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<int (*)[2], std::vector<int [2]> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = int (*)[2]]’:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:893:4: required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int [2]; _Alloc = std::allocator<int [2]>; std::vector<_Tp, _Alloc>::value_type = int [2]]’
basketball-match.cpp:145:49: required from here
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/vector.tcc:327:19: error: array must be initialized with a brace-enclosed initializer
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/vector.tcc:333:4: error: invalid array assignment
In file included from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/x86_64-unknown-linux-gnu/bits/c++allocator.h:34:0,
from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/allocator.h:48,
from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/stl_tree.h:64,
from /usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/map:60,
from /usr/include/openmpi/ompi/mpi/cxx/mpicxx.h:38,
from /usr/include/mpi.h:2087,
from basketball-match.cpp:1:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, const _Tp&) [with _Tp = int [2]; __gnu_cxx::new_allocator<_Tp>::pointer = int (*)[2]]’:
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ext/alloc_traits.h:202:9: required from ‘static void __gnu_cxx::__alloc_traits<_Alloc>::construct(_Alloc&, __gnu_cxx::__alloc_traits<_Alloc>::pointer, const _Tp&) [with _Tp = int [2]; _Alloc = std::allocator<int [2]>; __gnu_cxx::__alloc_traits<_Alloc>::pointer = int (*)[2]]’
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/bits/stl_vector.h:885:6: required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = int [2]; _Alloc = std::allocator<int [2]>; std::vector<_Tp, _Alloc>::value_type = int [2]]’
basketball-match.cpp:145:49: required from here
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.2/../../../../include/c++/4.7.2/ext/new_allocator.h:120:9: error: parenthesized initializer in array new [-fpermissive]
Source can be found on GitHub. What might be the cause?
Your problem is here
vector<int[2]> playersAtBall;
The type of the vector element must be copy-constructible. An array is not. So you can't have a vector<int[2]>. You could wrap your array into a copy constructible struct, or use std::pair<int, int> instead.
If you have C++11 compiler you can use std::array<int,2>, as mfontanini point out in the comment. If you don't, but are willing to use boost, you can use boost::array<int, 2>