Initialising vectors in constructors c++ - c++

I promise I've looked around for ages to find a solution to this, but to no avail, however I'm not experienced in C++ so maybe I just didn't know what to search for.
I suppose the easiest thing to do is to show you my error code first, in case it can be recognised. It's a bit of a heap, which is why I can't get my head around it to figure out what's wrong. (Also why I think it's something either out of my understanding, or a really annoying mistake I made!)
g++ -Wall -pedantic -ansi -std=c++0x -g -c -o contacts.o contacts.cc
In file included from /usr/include/c++/4.6/vector:63:0,
from contacts.h:5,
from contacts.cc:2:
/usr/include/c++/4.6/bits/stl_construct.h: In function ‘void std::_Construct(_T1*,
_Args&& ...) [with _T1 = person, _Args = {}]’:
/usr/include/c++/4.6/bits/stl_uninitialized.h:481:3: instantiated from ‘static void
std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator,
_Size) [with _ForwardIterator = person*, _Size = unsigned int, bool _TrivialValueType =
false]’
/usr/include/c++/4.6/bits/stl_uninitialized.h:529:7: instantiated from ‘void
std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator =
person*, _Size = unsigned int]’
/usr/include/c++/4.6/bits/stl_uninitialized.h:604:7: instantiated from ‘void
std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with
_ForwardIterator = person*, _Size = unsigned int, _Tp = person]’
/usr/include/c++/4.6/bits/stl_vector.h:1134:2: instantiated from ‘void
std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type)
[with _Tp = person, _Alloc = std::allocator<person>, std::vector<_Tp,
_Alloc>::size_type = unsigned int]’
/usr/include/c++/4.6/bits/stl_vector.h:239:9: instantiated from ‘std::vector<_Tp,
_Alloc>::vector(std::vector<_Tp, _Alloc>::size_type) [with _Tp = person, _Alloc =
std::allocator<person>, std::vector<_Tp, _Alloc>::size_type = unsigned int]’
contacts.cc:7:38: instantiated from here
Edit:
Apologies, I don't completely understand what I'm doing, but I hope this is what you asked for. The error still appears if I have at the very least this much in my code (The two relevant files):
Contacts.h:
#ifndef _CONTACTS_H
#define _CONTACTS_H
#include <iostream>
#include <vector>
#include "person.h"
class contacts{
private:
int element;
int count;
vector<person> pv;
public:
contacts();
};
#endif
and contacts.cc:
#include "contacts.h"
using namespace std;
contacts::contacts() : count(0), pv(0) {}
Thanks
-Ewan

Why are you passing 0 to the std::vector<> constructor? This sounds like it has the same effect from what you've written:
contacts::contacts() : count(0) {}

Related

C++ Assignment not compiling with G++ but is on Visual Studio

This is a very rushed assignment, just a few days ago my laptop had died with all of my progress so I had little time to make everything with this work.
I am having a (what feels like big) error with compiling my project with G++. Especially when i did all of my testing on visual studio (and had no errors)
I would run
g++ -std=c++11 ksim.cpp -o test
I believe that the error is connected to my two-dimensional arrays, but am not 100%.
Is there a setting inside of Visual Studio that I am missing to check how its compiling everything?
// Nathan Vassell
// CS 245 - Assignment 4
#include <iostream>
#include <iomanip>
#include <string>
#include <queue>
#include <sstream>
/*#include <locale>*/
using namespace std;
// Global variables
int ticks = 0;
string userInput;
string processes[256];
string blockedProcesses[10][3];
queue <string[10][3]> blockedQ2;
queue<string> newQ;
queue<string> readyQ;
queue<string> runningQ;
queue<string> blockedQ;
queue<string> exitQ;
int main()
{
return 0;
}
The Error im getting
In file included from /usr/include/c++/4.8.2/deque:62:0,
from /usr/include/c++/4.8.2/queue:60,
from ksim.cpp:8:
/usr/include/c++/4.8.2/bits/stl_construct.h: In instantiation of ‘void std::_Des troy(_Tp*) [with _Tp = std::basic_string<char> [10][3]]’:
/usr/include/c++/4.8.2/bits/stl_construct.h:103:46: required from ‘static void std::_Destroy_aux<<anonymous> >::__destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::basic_string<char> (*)[10][3]; bool <anonymous> = false]’
/usr/include/c++/4.8.2/bits/stl_construct.h:127:27: required from ‘void std::_ Destroy(_ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::basic_ string<char> (*)[10][3]]’
/usr/include/c++/4.8.2/bits/stl_construct.h:151:31: required from ‘void std::_ Destroy(_ForwardIterator, _ForwardIterator, std::allocator<_T2>&) [with _Forward Iterator = std::basic_string<char> (*)[10][3]; _Tp = std::basic_string<char> [10 ][3]]’
/usr/include/c++/4.8.2/bits/deque.tcc:807:31: required from ‘void std::deque<_ Tp, _Alloc>::_M_destroy_data_aux(std::deque<_Tp, _Alloc>::iterator, std::deque<_ Tp, _Alloc>::iterator) [with _Tp = std::basic_string<char> [10][3]; _Alloc = std ::allocator<std::basic_string<char> [10][3]>; std::deque<_Tp, _Alloc>::iterator = std::_Deque_iterator<std::basic_string<char> [10][3], std::basic_string<char> (&)[10][3], std::basic_string<char> (*)[10][3]>]’
/usr/include/c++/4.8.2/bits/stl_deque.h:1853:39: required from ‘void std::dequ e<_Tp, _Alloc>::_M_destroy_data(std::deque<_Tp, _Alloc>::iterator, std::deque<_T p, _Alloc>::iterator, const std::allocator<_CharT>&) [with _Tp = std::basic_stri ng<char> [10][3]; _Alloc = std::allocator<std::basic_string<char> [10][3]>; std: :deque<_Tp, _Alloc>::iterator = std::_Deque_iterator<std::basic_string<char> [10 ][3], std::basic_string<char> (&)[10][3], std::basic_string<char> (*)[10][3]>]’
/usr/include/c++/4.8.2/bits/stl_deque.h:918:62: required from ‘std::deque<_Tp, _Alloc>::~deque() [with _Tp = std::basic_string<char> [10][3]; _Alloc = std::al locator<std::basic_string<char> [10][3]>]’
ksim.cpp:19:23: required from here
/usr/include/c++/4.8.2/bits/stl_construct.h:93:7: error: request for member ‘~st d::basic_string<char> [10][3]’ in ‘* __pointer’, which is of non-class type ‘std ::basic_string<char> [10][3]’
{ __pointer->~_Tp(); }
^
-bash-4.2$

std::vector of class with private constructor does not compile when using modern C++

The code I'm working on was initially designed using C++03, and compiles and functions without errors using g++ -std=c++03. My goal is to have the same code compile using g++ -std=c++17.
The code contains a MyClass which contains a NestedClass. Only MyClassshould be able to use, create, and modify instances of NestedClass, which are stored in a std::vector< NestedClass >. As such NestedClass contains a private constructor, and declares MyClass and std::vector< NestedClass > as friends.
Minimal Example:
#include <vector>
class MyClass {
public:
class NestedClass {
friend class MyClass;
friend class std::vector< NestedClass >;
double _d;
NestedClass( double d = 0.0 ) : _d(d){ }
};
private:
std::vector< NestedClass > data;
public:
MyClass(){
data.resize( 40 );
}
};
int main(){
MyClass myclass = MyClass();
return 0;
}
This minimal example fails when compiling -std=c++17 with the following error:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = MyClass::NestedClass; _Args = {}]’:
/usr/include/c++/7/bits/stl_uninitialized.h:527:18: required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = MyClass::NestedClass*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:583:20: required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = MyClass::NestedClass*; _Size = long unsigned int]’
/usr/include/c++/7/bits/stl_uninitialized.h:645:44: required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = MyClass::NestedClass*; _Size = long unsigned int; _Tp = MyClass::NestedClass]’
/usr/include/c++/7/bits/vector.tcc:563:35: required from ‘void std::vector<_Tp, _Alloc>::_M_default_append(std::vector<_Tp, _Alloc>::size_type) [with _Tp = MyClass::NestedClass; _Alloc = std::allocator<MyClass::NestedClass>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/7/bits/stl_vector.h:692:21: required from ‘void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = MyClass::NestedClass; _Alloc = std::allocator<MyClass::NestedClass>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
bug.cpp:21:20: required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: ‘MyClass::NestedClass::NestedClass(double)’ is private within this context
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bug.cpp:11:4: note: declared private here
NestedClass( double d = 0.0 ) : _d(d){ }
How can I rewrite the code so that it compiles using c++17?
Changing std::vector< NestedClass > to std::vector< NestedClass * > is not an option since it would require rewriting code that uses MyClass which I do not control.
The minimalistic fix for your particular example is
data.resize( 40, {} );
Call the private constructor yourself, so that vector only needs to call the (implicitly declared) public ones.
In general, befriending something in a library you don't control doesn't work. You have no idea whether said something is actually going to delegate the work to something else.
In vector's case, it is pretty much required to delegate said work to something else.
A proper fix will likely involve changes to the classes involved. One possibility is the passkey idiom: make the constructors public, but only callable with an argument of a private type.

Finding the actual source for an error message from a template instantiation / type deduction

I am getting some error in a templated function of some 3rd party library that I am trying to build.
MSVC points to the function and told me that I am doing something wrong for a specific call. How can I know at which call exactly the error happens?
If it matters, this is the function:
template <typename T>
std::string ToString(T number) {
std::ostringstream ss;
ss << std::setprecision(NUM_TO_STRING_PRECISION);
ss << number;
return ss.str();
}
The error is:
Error C2088 '<<': illegal for class
How can I know at which call exactly the error happens?
Not really with visual-studio, but let's look at a simple example:
#include <vector>
struct Foo {
Foo() = delete;
};
int main() {
std::vector<Foo> vfoo(15);
(void)vfoo;
}
GCC g++ outputs these error messages:
In file included from /usr/local/include/c++/7.1.0/vector:63:0,
from main.cpp:1:
/usr/local/include/c++/7.1.0/bits/stl_uninitialized.h: In instantiation of 'static _ForwardIterator std::__uninitialized_default_n_1<true>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int]':
/usr/local/include/c++/7.1.0/bits/stl_uninitialized.h:583:20: required from '_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Foo*; _Size = long unsigned int]'
/usr/local/include/c++/7.1.0/bits/stl_uninitialized.h:645:44: required from '_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = Foo*; _Size = long unsigned int; _Tp = Foo]'
/usr/local/include/c++/7.1.0/bits/stl_vector.h:1347:36: required from 'void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]'
/usr/local/include/c++/7.1.0/bits/stl_vector.h:285:30: required from 'std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = Foo; _Alloc = std::allocator<Foo>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Foo>]'
main.cpp:9:29: required from here
/usr/local/include/c++/7.1.0/bits/stl_uninitialized.h:548:37: error: use of deleted function 'Foo::Foo()'
return std::fill_n(__first, __n, _ValueType());
^~~~~~~~~~~~
main.cpp:4:5: note: declared here
Foo() = delete;
^~~
IIRC it's very similar in visual studio. Just open the raw output tab, and go to the very last note, which probably contains the real source of the error.
MSVC results with rextester. Again the very last notes for source_file.cpp point to the real source of the error.

Compiler errors with std::reference_wrapper

#include <functional>
#include <algorithm>
#include <list>
using namespace std;
struct foo{
int _val;
};
int main(){
list<foo> A;
foo B;
for(int i=0;i<10;++i){
B._val=i;
A.push_back(B);
}
list< reference_wrapper < foo > > C(A.begin(),A.end());
return 0;
}
I am trying to use std::reference_wrapper to hold references to type "foo" but when I do this I get a very peculiar compiler error:
>In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/list:63,
from ref_wrapper.cpp:4:/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h: In member function \u2018void std::list<_Tp, _Alloc>::_M_initialize_dispatch(_InputIterator, _InputIterator, std::__false_type) [with _InputIterator = std::_List_iterator<foo>, _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]\u2019:
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:577: instantiated from \u2018std::list<_Tp, _Alloc>::list(_InputIterator, _InputIterator, const _Alloc&) [with _InputIterator = std::_List_iterator<foo>, _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]\u2019
ref_wrapper.cpp:19: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:1361: error: no matching function for call to \u2018std::list<std::reference_wrapper<foo>, std::allocator<std::reference_wrapper<foo> > >::push_back(foo&)\u2019
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:919: note: candidates are: void std::list<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]
/usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/bits/stl_list.h:924: note: void std::list<_Tp, _Alloc>::push_back(_Tp&&) [with _Tp = std::reference_wrapper<foo>, _Alloc = std::allocator<std::reference_wrapper<foo> >]
It is impossible to discern what is going on. I have tried the same code on VS 2010 and it worked. I am wondering why it's not working for g++
The command I entered in terminal was:
g++ -std=gnu++0x reference_wrapper_test.cpp -o reference_wrapper_test
I think that you could update your compiler .
See the Link : http://liveworkspace.org/code/3mVcGp$6

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>