Signature of Generated operator=()? - c++

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

Related

Strange error using a class array for a thread C++

I'm trying to do a Thread calling the cook class through a vector but I don't know to do it correctly. Here is my code:
for (int i = 0; i < _numCooks; i++) {
std::thread threadObj(this->_cooks[i].nextOrder, void);
_threads.push_back(threadObj);
}
_cooks is a vector of a class and the function that I am trying to make a thread of is:
bool cooks::nextOrder()
{
Margarita margarita(_cookOrder[0].pizzaSize);
Regina regina(_cookOrder[0].pizzaSize);
Fantasia fantasia(_cookOrder[0].pizzaSize);
Americana americana(_cookOrder[0].pizzaSize);
if (_cookOrder.empty())
return (false);
switch (_cookOrder[0].pizzaType) {
case plazza::Margarita:
return (makeOrder(margarita));
break;
case plazza::Regina:
return (makeOrder(regina));
break;
case plazza::Fantasia:
return (makeOrder(fantasia));
break;
case plazza::Americana:
return (makeOrder(americana));
break;
default:
return (false);
}
}
however when I try to compile I get this:
kitchen/kitchen.cpp: In member function ‘void
Kitchen::make_pizza(std::__cxx11::string, std::__cxx11::string, Ipc)’:
kitchen/kitchen.cpp:148:59: error: expected primary-expression before
‘void’
std::thread threadObj(this->_cooks[i].nextOrder, void);
^~~~ kitchen/kitchen.cpp:148:63: error: invalid use of non-static member
function ‘bool cooks::nextOrder()’
std::thread threadObj(this->_cooks[i].nextOrder, void);
^ In file included from kitchen/kitchen.hpp:17,
from kitchen/kitchen.cpp:5: kitchen/cooks.hpp:32:10: note: declared here
bool nextOrder();
^~~~~~~~~ In file included from /usr/include/c++/8/x86_64-redhat-linux/bits/c++allocator.h:33,
from /usr/include/c++/8/bits/allocator.h:46,
from /usr/include/c++/8/string:41,
from /usr/include/c++/8/bits/locale_classes.h:40,
from /usr/include/c++/8/bits/ios_base.h:41,
from /usr/include/c++/8/ios:42,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from kitchen/../pizza/IPizza.hpp:23,
from kitchen/../pizza/APizza.hpp:11,
from kitchen/kitchen.hpp:8,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/ext/new_allocator.h: In instantiation of ‘void
__gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = cooks; _Args = {const cooks&}; _Tp = cooks]’: /usr/include/c++/8/bits/alloc_traits.h:475:4: required from ‘static
void std::allocator_traits
::construct(std::allocator_traits >::allocator_type&, _Up*, _Args&& ...) [with _Up = cooks; _Args = {const cooks&}; _Tp = cooks;
std::allocator_traits >::allocator_type =
std::allocator]’ /usr/include/c++/8/bits/stl_vector.h:1079:30:
required from ‘void std::vector<_Tp, _Alloc>::push_back(const
value_type&) [with _Tp = cooks; _Alloc = std::allocator;
std::vector<_Tp, _Alloc>::value_type = cooks]’
kitchen/kitchen.cpp:36:30: required from here
/usr/include/c++/8/ext/new_allocator.h:136:4: error: use of deleted
function ‘cooks::cooks(const cooks&)’ { ::new((void )__p)
_Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from kitchen/kitchen.hpp:17,
from kitchen/kitchen.cpp:5: kitchen/cooks.hpp:21:7: note: ‘cooks::cooks(const cooks&)’ is implicitly deleted because the
default definition would be ill-formed: class cooks
^~~~~ kitchen/cooks.hpp:21:7: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const
std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits =
std::char_traits]’ In file included from
kitchen/../plazza.hpp:15,
from kitchen/kitchen.hpp:13,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/fstream:778:7: note: declared here
basic_ofstream(const basic_ofstream&) = delete;
^~~~~~~~~~~~~~ In file included from /usr/include/c++/8/vector:62,
from kitchen/../pizza/IPizza.hpp:24,
from kitchen/../pizza/APizza.hpp:11,
from kitchen/kitchen.hpp:8,
from kitchen/kitchen.cpp:5: /usr/include/c++/8/bits/stl_construct.h: In instantiation of ‘void
std::_Construct(_T1, _Args&& ...) [with _T1 = cooks; _Args =
{cooks}]’: /usr/include/c++/8/bits/stl_uninitialized.h:83:18:
required from ‘static _ForwardIterator
std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*; bool
_TrivialValueTypes = false]’ /usr/include/c++/8/bits/stl_uninitialized.h:134:15: required from
‘_ForwardIterator std::uninitialized_copy(_InputIterator,
_InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*]’
/usr/include/c++/8/bits/stl_uninitialized.h:289:37: required from
‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator,
_InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator; _ForwardIterator = cooks*; _Tp = cooks]’
/usr/include/c++/8/bits/stl_uninitialized.h:311:2: required from
‘_ForwardIterator
std::__uninitialized_move_if_noexcept_a(_InputIterator,
_InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = cooks*; _ForwardIterator = cooks*; _Allocator =
std::allocator]’ /usr/include/c++/8/bits/vector.tcc:447:6:
required from ‘void std::vector<_Tp,
_Alloc>::_M_realloc_insert(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const cooks&}; _Tp = cooks; _Alloc =
std::allocator; std::vector<_Tp, _Alloc>::iterator =
__gnu_cxx::__normal_iterator >; typename std::_Vector_base<_Tp, _Alloc>::pointer = cooks*]’
/usr/include/c++/8/bits/stl_vector.h:1085:4: required from ‘void
std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp =
cooks; _Alloc = std::allocator; std::vector<_Tp,
_Alloc>::value_type = cooks]’ kitchen/kitchen.cpp:36:30: required from here /usr/include/c++/8/bits/stl_construct.h:75:7: error: use of
deleted function ‘cooks::cooks(const cooks&)’
{ ::new(static_cast(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make: *** [: kitchen/kitchen.o] Error 1
Is there any way to fix it?
According to this, the first argument to a std::thread constructor should meet the Callable concept. You then pass the subsequent arguments for the Callable as additional arguments to the constructor.
You're passing a member function. You need an instance of the class to call the method on, which you're not providing. This is what this error should mean to you.
error: invalid use of non-static member function ‘bool cooks::nextOrder()’
It's probably easiest to use a lambda ie.
for (int i = 0; i < _numCooks; i++) {
_threads.emplace_back([&cook = _cooks[i]]() {
cook.nextOrder();
});
}

Error calling both set_rdbuf and rdbuf on std::ifstream

Below is some code I wrote in c++.
ifstream objfile(s1.c_str());
string s2 = strfile;
std::istringstream objstr(s2);
if (path.empty()) objfile.set_rdbuf(objstr.rdbuf());
It has no problem compile in Visual Studio C++ 2017. When I try to compile using g++ in redhat linux, it has error
error: ‘std::ifstream’ has no member named ‘set_rdbuf’
Edit: Based on the initial answers to this question, I tried replacing the call to set_rdbuf with
objfile.rdbuf(objstr.rdbuf());
This still does not work. It says
rdbuf() const, note: candidate expects 0 arguments, 1 provided.
The full error messages is really long, I removed the lines of In files included from ...
error: no matching function for call to ‘std::basic_ifstream<char>::rdbuf(std::basic_istringstream<char>::__stringbuf_type*)’
if(path.empty()) objfile.rdbuf(objstr.rdbuf());
^
/usr/include/c++/4.8.2/fstream:509:7: note: std::basic_ifstream<_CharT, _Traits>::__filebuf_type* std::basic_ifstream<_CharT, _Traits>::rdbuf() const [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ifstream<_CharT, _Traits>::__filebuf_type = std::basic_filebuf<char>]
rdbuf() const
^
error: no matching function for call to ‘std::basic_ifstream<char>::rdbuf(std::basic_istringstream<char>::__stringbuf_type*)’
if (path.empty()) objfile.rdbuf(objstr.rdbuf());
^
/usr/include/c++/4.8.2/fstream:509:7: note: std::basic_ifstream<_CharT, _Traits>::__filebuf_type* std::basic_ifstream<_CharT, _Traits>::rdbuf() const [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ifstream<_CharT, _Traits>::__filebuf_type = std::basic_filebuf<char>]
rdbuf() const
^
/usr/include/c++/4.8.2/fstream:509:7: note: candidate expects 0 arguments, 1 provided
/usr/include/c++/4.8.2/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>]’:
/usr/include/c++/4.8.2/bits/alloc_traits.h:254:4: required from ‘static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Alloc = std::allocator<std::basic_istringstream<char> >; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]’
/usr/include/c++/4.8.2/bits/alloc_traits.h:393:57: required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Alloc = std::allocator<std::basic_istringstream<char> >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.8.2/bits/vector.tcc:97:40: required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/stl_vector.h:920:36: required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >; std::vector<_Tp, _Alloc>::value_type = std::basic_istringstream<char>]’
/home/research/QZ/6_compile_Agency_Model/Agency_files/BondModel/utility.h:2413:37: required from here
/usr/include/c++/4.8.2/ext/new_allocator.h:120:4: error: use of deleted function ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
In file included from /usr/include/c++/4.8.2/complex:45:0,
from /home/research/boost_library/boost_1_68_0/boost/detail/container_fwd.hpp:98,
from /home/research/boost_library/boost_1_68_0/boost/container_hash/extensions.hpp:22,
from /home/research/boost_library/boost_1_68_0/boost/container_hash/hash.hpp:760,
from /home/research/boost_library/boost_1_68_0/boost/type_index/stl_type_index.hpp:42,
from /home/research/boost_library/boost_1_68_0/boost/type_index.hpp:29,
from /home/research/boost_library/boost_1_68_0/boost/any.hpp:20,
from /home/research/boost_library/boost_1_68_0/boost/program_options/value_semantic.hpp:12,
from /home/research/boost_library/boost_1_68_0/boost/program_options/options_description.hpp:13,
/usr/include/c++/4.8.2/sstream:272:11: note: ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_istringstream : public basic_istream<_CharT, _Traits>
^
/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’
/usr/include/c++/4.8.2/istream:58:11: note: ‘std::basic_istream<char>::basic_istream(const std::basic_istream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_istream : virtual public basic_ios<_CharT, _Traits>
^
/usr/include/c++/4.8.2/istream:58:11: error: use of deleted function ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’
/usr/include/c++/4.8.2/bits/basic_ios.h:66:11: note: ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_ios : public ios_base
^
/usr/include/c++/4.8.2/bits/ios_base.h:786:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
ios_base(const ios_base&);
^
/usr/include/c++/4.8.2/bits/basic_ios.h:66:11: error: within this context
class basic_ios : public ios_base
^
/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’
class basic_istringstream : public basic_istream<_CharT, _Traits>
^
/usr/include/c++/4.8.2/sstream:272:11: error: use of deleted function ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’
/usr/include/c++/4.8.2/sstream:64:11: note: ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’ is implicitly deleted because the default definition would be ill-formed:
class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
^
/usr/include/c++/4.8.2/streambuf:802:7: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’ is private
basic_streambuf(const basic_streambuf& __sb)
^
/usr/include/c++/4.8.2/sstream:64:11: error: within this context
class basic_stringbuf : public basic_streambuf<_CharT, _Traits>
^
In file included from /usr/include/c++/4.8.2/vector:62:0,
/usr/include/c++/4.8.2/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::basic_istringstream<char>; _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}]’:
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:75:53: required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*; bool _TrivialValueTypes = false]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:117:41: required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<std::basic_istringstream<char>*>; _ForwardIterator = std::basic_istringstream<char>*; _Tp = std::basic_istringstream<char>]’
/usr/include/c++/4.8.2/bits/stl_uninitialized.h:281:69: required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = std::basic_istringstream<char>*; _ForwardIterator = std::basic_istringstream<char>*; _Allocator = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/vector.tcc:415:43: required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/vector.tcc:101:54: required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >}; _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >]’
/usr/include/c++/4.8.2/bits/stl_vector.h:920:36: required from ‘void std::vector<_Tp, _Alloc>::push_back(std::vector<_Tp, _Alloc>::value_type&&) [with _Tp = std::basic_istringstream<char>; _Alloc = std::allocator<std::basic_istringstream<char> >; std::vector<_Tp, _Alloc>::value_type = std::basic_istringstream<char>]’
/home/research/QZ/6_compile_Agency_Model/Agency_files/BondModel/utility.h:2413:37: required from here
/usr/include/c++/4.8.2/bits/stl_construct.h:75:7: error: use of deleted function ‘std::basic_istringstream<char>::basic_istringstream(const std::basic_istringstream<char>&)’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
make[2]: *** [CMakeFiles/BondModel.dir/cashflowengine.cpp.o] Error 1
make[1]: *** [CMakeFiles/BondModel.dir/all] Error 2
This is quite interesting. As others have noted, the initial issue here is that the set_rdbuf member function is protected, so you can’t call it directly. I was surprised when you reported that calling the correct member function rdbuf didn’t compile, because that member function does exist and is public.
The short version is that I believe the following code will do what you want:
if (path.empty()) objfile.istream::rdbuf(objstr.rdbuf());
The reason you need the istream:: prefix here has to do with how C++ does name lookups in derived classes. If a derived class declares a member function with a given name and you try to call a function with that name, the compiler will not look to base classes to find potential overloads for that function. In C++11, the ifstream type had a new helper function added called rdbuf that returns the underlying buffer as a filebuf*. This shadows the istream function rdbuf that sets the underlying buffer. As a result, if call the one-argument version of rdbuf, C++ won’t find it because it stops searching as soon as it finds the zero-argument rdbuf defined in ifstream. Adding the explicit istream::rdbuf call tells the compiler to search for this function in istream first, where it ends up finding the function you want.
Hope this helps!
std::ifstream::set_rdbuf is protected, as mentioned here. It's possible that MSVC exposes it as a public member function in std::ifstream which would explain why your code compiles there.
What you want is rdbuf:
std::basic_streambuf<CharT, Traits>* rdbuf( std::basic_streambuf<CharT, Traits>* sb );
Sets the associated stream buffer to sb. The error state is cleared by calling clear(). Returns the associated stream buffer before the operation. If there is no associated stream buffer, returns a null pointer.
set_rdbuf is a protected member function. That is why it is not accessible.

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;
}

can't push my object to std::vector - gcc can't find something like copy-construct

I'm using such field:
std::vector<OneItemIndex> oneItemIndexes;
This is part of OneItemIndex declaration:
class OneItemIndex : public CustomIndex
{
public:
OneItemIndex(int instrumentId_);
~OneItemIndex(void);
OneItemIndex(OneItemIndex& rhs);
...
In VC++ this compiles just fine, but in gcc I receive such compilation error:
In file included from /usr/include/c++/4.8/vector:62:0,
from ../IndexesStorage.h:4,
from ../IndexesStorage.cpp:1:
/usr/include/c++/4.8/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = OneItemIndex; _Args = {OneItemIndex}]’:
/usr/include/c++/4.8/bits/stl_uninitialized.h:75:53: required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<OneItemIndex*>; _ForwardIterator = OneItemIndex*; bool _TrivialValueTypes = false]’
/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<OneItemIndex*>; _ForwardIterator = OneItemIndex*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<OneItemIndex*>; _ForwardIterator = OneItemIndex*; _Tp = OneItemIndex]’
/usr/include/c++/4.8/bits/stl_vector.h:1142:29: required from ‘std::vector<_Tp, _Alloc>::pointer std::vector<_Tp, _Alloc>::_M_allocate_and_copy(std::vector<_Tp, _Alloc>::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator<OneItemIndex*>; _Tp = OneItemIndex; _Alloc = std::allocator<OneItemIndex>; std::vector<_Tp, _Alloc>::pointer = OneItemIndex*; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/4.8/bits/vector.tcc:75:70: required from ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = OneItemIndex; _Alloc = std::allocator<OneItemIndex>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
../IndexesStorage.cpp:197:55: required from here
/usr/include/c++/4.8/bits/stl_construct.h:75:7: error: no matching function for call to ‘OneItemIndex::OneItemIndex(OneItemIndex)’
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^
/usr/include/c++/4.8/bits/stl_construct.h:75:7: note: candidates are:
In file included from ../IndexesStorage.h:7:0,
from ../IndexesStorage.cpp:1:
../OneItemIndex.h:13:2: note: OneItemIndex::OneItemIndex(OneItemIndex&)
OneItemIndex(OneItemIndex& rhs);
^
../OneItemIndex.h:13:2: note: no known conversion for argument 1 from ‘OneItemIndex’ to ‘OneItemIndex&’
../OneItemIndex.h:8:2: note: OneItemIndex::OneItemIndex(int)
OneItemIndex(int instrumentId_);
^
../OneItemIndex.h:8:2: note: no known conversion for argument 1 from ‘OneItemIndex’ to ‘int’
Why gcc asks for OneItemIndex::OneItemIndex(OneItemIndex)? Should I add such construction, how to implement it?
Change
OneItemIndex(OneItemIndex& rhs);
to
OneItemIndex(OneItemIndex const& rhs);
in the class definition.

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>