How to declare a vector in a hpp? - c++

Hello I know that to declare a std::vector I have to do like this
std::vector<double> a(0);
But in my file it does not work. Here is my code :
main.cpp :
#include "test.hpp"
int main()
{
Test test;
return EXIT_SUCCESS;
}
test.hpp :
#ifndef DEF_TEST
#define DEF_TEST
#include <iostream>
#include <vector>
class Test
{
public:
Test();
private:
std::vector<double> a(0);
};
#endif
and this is test.cpp :
#include "test.hpp"
Test::Test()
{
a.push_back(2.3);
std::cout << a[0] << std::endl;
}
And the compiler told me :
In file included from main.cpp:1:0:
test.hpp:11:23: error: expected identifier before numeric constant
std::vector<double> a(0);
^
test.hpp:11:23: error: expected ‘,’ or ‘...’ before numeric constant
In file included from test.cpp:1:0:
test.hpp:11:23: error: expected identifier before numeric constant
std::vector<double> a(0);
^
test.hpp:11:23: error: expected ‘,’ or ‘...’ before numeric constant
test.cpp: In constructor ‘Test::Test()’:
test.cpp:5:1: error: ‘((Test*)this)->Test::a’ does not have class type
a.push_back(2.3);
^
test.cpp:6:17: error: invalid types ‘<unresolved overloaded function type>[int]’ for array subscript
std::cout << a[0] << std::endl;
Thank you for your help !

It seems to me that you can not use a constructor for a member declaration of a class; to use constructors for the vector in a class you must specify it in a constructor for the class, e.g.
class Test {
private:
vector<double> a;
public:
Test() : a(0) {;}
};

You can initialize a variable using the following syntax:
std::vector<double> a(0);
but you can't use that for in-class initialization of class members. To initialize a member in-class, you can use the following syntax:
std::vector<double> a = {};

std::vector members will get initialized by the default initializer once an instance of your class is created.
If you want to call the vector initializer explicitly you can do it this way in your Test.cpp file:
Test::Test():
a(0) {
//...
}
Ps. An advantage of this is that you also can initialize constants that are members of your class.

You must do the following to initialize the vector as a class member:
class Test{
public:
Test();
private:
std::vector<double> a = std::vector<double>(0);
};
FYI, this code sizes the vector to 0, which is redundant. You can simply write std::vector<double> a and its size will be 0 to begin with. In other cases, if you want the vector to be of size n, then you use the method I've written with n instead of 0.

You can use an initialiser list for this after your constructer
Test::Test() : a(0)
{
...
}
You need to remove the (0) from your .hpp file.

Related

"result type must be constructible from value type of input range" when creating a std::vector

I have a class member that looks like this
class Controller {
protected:
// other stuff
std::vector<Task<event_t, stackDepth>> taskHandlers;
//some more stuf
}
The Task class is non-defaultConstructible, non-copyConstructible, non-copyAssignable but is moveConstructible and moveAssignable. Everything I could read (notably, std::vector documentation) leads me to think that this should compile, but the error list looks like this (full output here) :
/usr/include/c++/9/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range
127 | static_assert(is_constructible<_ValueType2, decltype(*__first)>::value,
| ^~~~~
Making Task defaultConstructible did not help. The error points to the definition of the class Controller. I am using GCC 9.3.0 in c++17 mode. Did I do anything wrong ?
My best guess, given the current information, is that you messed up the move constructor syntax somehow - working example using just emplace_back:
The below compiles fine, link to godbolt:
#include <vector>
class X
{
public:
X(int i) : i_(i){}
X() = delete;
X(const X&) = delete;
X(X&&) = default;//change this to 'delete' will give a similar compiler error
private:
int i_;
};
int main() {
std::vector<X> x;
x.emplace_back(5);
}
to reproduce the error result type must be constructible from value type of input range
godbolt
#include <vector>
#include <string>
#include <iostream>
int main() {
typedef std::vector<std::string> StrVec;
StrVec s1("a", "b"); // error
// stl_uninitialized.h:127:7: error: static_assert failed due to requirement 'is_constructible<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, const char &>::value' "result type must be constructible from value type of input range"
//StrVec s2("a", "b", "c"); // error
// error: no matching constructor for initialization of 'StrVec' (aka 'vector<basic_string<char> >')
StrVec s3({"a", "b"}); // ok
StrVec s4({"a", "b", "c"}); // ok
typedef std::vector<int> IntVec;
IntVec i1(1, 2); // silent error
for (auto i : i1) {
std::cout << "i = " << i << '\n';
}
// silent error:
// output:
// i = 2
// expected:
// i = 1
// i = 2
//IntVec i2(1, 2, 3); // error
// error: no matching constructor for initialization of 'IntVec' (aka 'vector<int>')
IntVec i3({1, 2}); // ok
IntVec i4({1, 2, 3}); // ok
}

C++ error:expected ‘;’ at end of member declaration

#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test(){}
~test(){}
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();//build error
//shared_ptr<map<type, int>> member_ = make_shared<map<type, int>>();//build ok
};
int main()
{
return 0;
}
when i compile program with "shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>()"
main.cpp:17:63: error: expected ‘;’ at end of member declaration
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:67: error: expected unqualified-id before ‘>>’ token
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:58: error: wrong number of template arguments (1, should be at least 2)
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
In file included from /usr/include/c++/5/map:61:0,
from main.cpp:1:
/usr/include/c++/5/bits/stl_map.h:96:11: note: provided for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’
class map
^
main.cpp:17:42: error: parse error in template argument list
shared_ptr<map<int, type>> member_ = make_shared<map<int, type>>();
^
main.cpp:17:42: error: cannot resolve overloaded function ‘make_shared’ based on conversion to type ‘std::shared_ptr<std::map<int, test::type> >’
Have tried your code with Online C++ Compiler, got the same errors with C++, C++11, and C++14 compatible compilers, but got compiled well with C++17 compatible compiler. This means that your code is not legal in C++ standards prior to C++17. As pointed out by others, the code, however, compiled well on other online compiler sites even with C++11 and C++14 standards. So I would guess the errors are due to supported / unsupported features of compilers.
Well, you are not supposed to initialize class members like this anyway. The initialization of class members should happen in the class constructor, like so:
#include <map>
#include <memory>
#include <iostream>
using namespace std;
class test
{
public:
test() { member_ = make_shared<map<int, type>>(); }
~test() { }
enum type
{
error = 0
};
private:
shared_ptr<map<int, type>> member_;
};
int main()
{
return 0;
}
This compiles fine even in Online C++ Compiler which is the only place we are managing to reproduce the problem.

error: expected constructor, destructor, or type conversion before '&' token for a user defined class in the source file

I am facing an error in one of my projects which I have replicated using a standalone program. I did see several posts pertinent to this, but could not figure out my problem. I am getting the following error with this code : "error: expected constructor, destructor, or type conversion before '&' token"
#include <iostream>
#include <boost/shared_ptr.hpp>
using namespace std;
class X
{
private:
int _x;
public:
X(int x) : _x(x) {};
};
class Y
{
private:
typedef boost::shared_ptr<X> X_ptr;
public:
X_ptr& func1();
};
X_ptr& Y::func1()
{
X_ptr p(new X(8));
return p;
};
int main()
{
return 0;
}
Can someon help me with in resolving this error?
There are two problems. First, you forgot to qualify the type name X_ptr:
Y::X_ptr& Y::func1()
// ^^^ ^
// BUT REMOVE THIS!
Second, notice that you are returning a reference to a local variable. Attempting to dereference the value returned by func1() will give you undefined behavior.
Just change the prototype of your function this way:
Y::X_ptr Y::func1()
// ^^^^^
// Returning the smart pointer by value now
{
X_ptr p(new X(8));
return p;
}

Struct in a list doesn't work

I have this code:
hpp:
#include <list>
using namespace std;
class funcionario
{
public:
struct Dia {
int d;
int h;
int id;
int tipo;
};
funcionario ();
void eliminar(int dia, int hora);
private:
list<Dia> agenda;
};
cpp:
#include "myClass.hpp"
funcionario::funcionario(){
agenda = list<Dia> ();
}
void funcionario::eliminar(int dia, int hora) {
list<funcionario::Dia>::iterator it;
it = agenda.begin();
while(it != agenda.end() && (*it).d <= dia) {
if((*it).d == dia && (*it).h == hora) {
agenda.erase(it);
return;
}
++it;
}
}
I get this compiling error:
Funcionario.cpp: In constructor ‘funcionario::funcionario()’:
Funcionario.cpp:5: error: cannot convert ‘std::list<funcionario::Dia, std::allocator<funcionario::Dia> >’ to ‘int’ in assignment
Funcionario.cpp: In member function ‘void funcionario::eliminar(int, int)’:
Funcionario.cpp:9: error: request for member ‘begin’ in ‘((funcionario*)this)->funcionario::agenda’, which is of non-class type ‘int’
Funcionario.cpp:10: error: request for member ‘begin’ in ‘((funcionario*)this)->funcionario::agenda’, which is of non-class type ‘int’
Funcionario.cpp:11: error: request for member ‘end’ in ‘((funcionario*)this)->funcionario::agenda’, which is of non-class type ‘int’
I don't know what I'm doing wrong.
Not sure what you're trying to achieve, but the code just needs to be fleshed out a bit with complete function definitions. I got this to compile:
#include <list>
class myClass
{
public:
myClass();
struct myStruct {
int myInfo;
};
void something();
void doSomething(myStruct & ms);
private:
std::list<myStruct> myList;
};
myClass::myClass(){
myList = list<myStruct> ();
}
void myClass::something() {
std::list<myStruct>::iterator it;
it = myList.begin();
while(it != myList.end()) {
doSomething(*it);
++it;
}
}
Incidentally (or maybe directly relevant, not sure) - the copy-initialization of myList in myClass() is unnecessary, as others have stated. The list<> default constructor will do the right thing, and more efficiently.
This seems to be working on my computer, so may it be a compiler problem? Try with another compiler and tell us if it worked
The initialization you're looking for is analogous to Initializing map and set class member variables to empty in C++? - but actually you'll get an empty list automatically (i.e. by the std::list default constructor).
--Edited to reflect your posting of the original code--
H is not declared anywhere.
and is not a valid C++ keyword or token. Use &&.
Use the local header include form of : #include "myClass.hpp"

How to properly use a header file to be a complete class?

(Beginner programmer..) I'm following the style of a header file that worked fine, but I'm trying to figure out how I keep getting all of these errors when I compile. I am compiling with g++ in Cygwin.
Ingredient.h:8:13: error: expected unqualified-id before ‘)’ token
Ingredient.h:9:25: error: expected ‘)’ before ‘n’
Ingredient.h:19:15: error: declaration of ‘std::string <anonymous class>::name’
Ingredient.h:12:14: error: conflicts with previous declaration ‘std::string<anonymous class>::name()’
Ingredient.h:20:7: error: declaration of ‘int <anonymous class>::quantity’
Ingredient.h:13:6: error: conflicts with previous declaration ‘int<anonymous class>::quantity()’
Ingredient.h: In member function ‘std::string<anonymous class>::name()’:
Ingredient.h:12:30: error: conversion from ‘<unresolved overloaded function type>’ to non-scalar type ‘std::string’ requested
Ingredient.h: In member function ‘int<anonymous class>::quantity()’:
Ingredient.h:13:25: error: argument of type ‘int (<anonymous class>::)()’ does not match ‘int’
Ingredient.h: At global scope:
Ingredient.h:4:18: error: an anonymous struct cannot have function members
Ingredient.h:21:2: error: abstract declarator ‘<anonymous class>’ used as declaration
And here is my class header file...
#ifndef Ingredient
#define Ingredient
class Ingredient {
public:
// constructor
Ingredient() : name(""), quantity(0) {}
Ingredient(std::string n, int q) : name(n), quantity(q) {}
// accessors
std::string name() { return name; }
int quantity() {return quantity; }
// modifier
private:
// representation
std::string name;
int quantity;
};
#endif
I am confused by these errors and don't really know what I am doing wrong concerning the implementation of the class..
That's a funny one. You are essentially killing your class name by #define Ingredient - all occurrences of Ingredient will be erased. This is why include guards generally take the form of #define INGREDIENT_H.
You are also using name both for the member and the getter function (probably an attempt to translate C#?). This is not allowed in C++.
How about look on errors? variables and functions can't have same names. And include guard should never names such as class.
#ifndef INGREDIENT_H
#define INGREDIENT_H
class Ingredient {
public:
// constructor
Ingredient() : name(""), quantity(0) {}
Ingredient(std::string n, int q) : name(n), quantity(q) {}
// accessors
std::string get_name() const { return name; }
int get_quantity() const {return quantity; }
// modifier
private:
// representation
std::string name;
int quantity;
};
#endif