C++ struct constructor - c++

I tried to create my own structure. So I wrote this piece of code.
struct node
{
int val, id;
node(int init_val, int init_id)
{
val = init_val;
id = init_id;
}
};
node t[100];
int main()
{
...
}
I tried to compile my program. But I got an error:
error: no matching function for call to 'node::node()'
note: candidates are:
note: node::node(int, int)
note: candidate expects 2 arguments, 0 provided
note: node::node(const node&)
note: candidate expects 1 argument, 0 provided

node t[100];
will try to initialise the array by calling a default constructor for node. You could either provide a default constructor
node()
{
val = 0;
id = 0;
}
or, rather verbosely, initialise all 100 elements explicitly
node t[100] = {{0,0}, {2,5}, ...}; // repeat for 100 elements
or, since you're using C++, use std::vector instead, appending to it (using push_back) at runtime
std::vector<node> t;

This will fix your error.
struct node
{
int val, id;
node(){};
node(int init_val, int init_id)
{
val = init_val;
id = init_id;
}
};
You should declare default constructor.

Related

How to initialize the array-like member variable in the constructor?

How to initialize the array-like member variable?
The visual studio code says:
no matching function for call to 'Node::Node()' gcc line 12 col 9
const int N = 100;
struct Node {
int val, ch[2];
/**
void init(int _val) {
this->val = _val, this->ch[0] = this->ch[1] = 0;
}*/
Node (int _val): val(_val) {
this->ch[0] = this->ch[1] = 0;
}
} tree[N]; // <--------- this is line 12
int main() {
int a;
cin >> a;
tree[0] = Node(a);
}
The problem is that when you wrote tree[N] you're creating an array whose elements will be default constructed but since there is no default constructor for your class Node, we get the mentioned error.
Also, Node doesn't have a default constructor because you've provided a converting constructor Node::Node(int) so that the compiler will not automatically synthesize the default ctor Note::Node().
To solve this you can add a default ctor Node::Node() for your class.

Compiler not recognizing the constructor, expects arguments and recognizes zero

I am trying to organize data into a binary tree and have created a struct to better organize the data. However, my compiler has this error message every time I try to run my code:
BinaryTree.cpp:41:37: error: no matching function for call to 'person::person()'
node (person i, node * l, node * r){
^
BinaryTree.cpp:14:2: note: candidate: 'person::person(int, int, std::__cxx11::string, std::__cxx11::string, int)'
person(int ss, int bd, string fn, string ln, int zc) {
^~~~~~
BinaryTree.cpp:14:2: note: candidate expects 5 arguments, 0 provided
BinaryTree.cpp:10:8: note: candidate: 'person::person(const person&)'
struct person {
^~~~~~
BinaryTree.cpp:10:8: note: candidate expects 1 argument, 0 provided
BinaryTree.cpp:10:8: note: candidate: 'person::person(person&&)'
BinaryTree.cpp:10:8: note: candidate expects 1 argument, 0 provided
The lines of code it is referring to, are these structs I created. I have used the person struct before and it works just fine so I am confused as to my error.
struct person {
int socialSecurity, birthDate, zipCode;
string firstName, lastName;
person(int ss, int bd, string fn, string ln, int zc) {
socialSecurity = ss;
birthDate = bd;
firstName = fn;
lastName = ln;
zipCode = zc;
}
};
struct node {
person info;
node * left, * right;
node (person i, node * l, node * r){
info = i;
left = l;
right = r;
}
};
I am a bit new to this so if you need more code to help me figure out what is wrong Ill try to provide as much as I can.
Since you defined a non-default constructor, the compiler will not generate a default constructor, see https://en.cppreference.com/w/cpp/language/default_constructor for more info.
To solve this, see default constructor not generated?.

How to do constructor for 2D vector in C++?

I tried initializing a 2D vector with a constructor in 3 different ways but always get an
"error: no matching function to call"
Could you tell me where I am wrong?
class Node
{
public:
int to;
int length;
Node(int to, int length) : to(to), length(length){}
};
class Graph
{
public:
vector<vector<Node>> nodes_list;
int n;
Graph();
};
Graph::Graph(){
nodes_list = vector<vector<Node> >(n, vector<Node>(n,0x3fffffff));
}
vector<Node>(n,0x3fffffff);
is (roughly) equivalent to:
vector<Node> v;
for ( size_t i = 0; i < n; i++ )
{
v.push_back(Node(0x3fffffff));
}
As your Node class doesn't have a constructor taking a single integer this fails to compile. The correct code is:
vector<Node>(n,Node(0x3fffffff,0));
By the way I assume you have using namespace std; in your header for Graph, don't do that, it will cause you issues at some point.
Your code has two problems:
At the following line, you should have provided the parameters for
constructing the Node, which are to and legth.
vector<vector<Node>>(n, vector<Node>(n,0x3fffffff));
// ^^^^^^^^^^^--> here
In Graph, the member n is un-initialized, at the
point, you call the default constructor. That would lead you to have
a garbage value in n and hence the size of the nodes_list would
be undefined.
The fixed code will look like:
struct Node
{
int _to;
int _length;
Node(int to, int length) : _to{ to }, _length{ length } {}
};
class Graph
{
using VecNode = std::vector<Node>; // type alias for convenience
private:
int _n;
std::vector<VecNode> _nodes_list;
public:
Graph()
: _n{ 2 } // initialize _n
, _nodes_list{ _n, VecNode(_n, { 1, 3 }) }
// ^^^^^^-> initialize with the default 'Node(1, 3)'
{}
};
Also some suggestions:
Use member initializer
lists
to initialize the vector, instead of creating and assign to it.
It's not a good idea to name both constructor parameters and the
members with same in Node. At some point, that may lead to
confusions.

constexpr linked list - invalid conversion from const X* to X*

Here's my attempt at creating a simple constexpr linked list -
struct Node
{
constexpr Node(const int n, Node const* next = nullptr)
: value(n), next(next) {}
constexpr Node push(const int n) const { return Node(n, this); }
int value;
Node const* next;
};
constexpr auto getSum(Node n) {
int sum = 0;
Node *current = &n;
while(current != nullptr) {
sum += current->value;
current = current->next;
}
return sum;
}
int main() {
constexpr Node a(0);
a.push(1);
a.push(22);
constexpr auto result = getSum(a);
return result;
}
on compiling this program, the following error is shown
prog.cc: In function 'constexpr auto getSum(Node)':
prog.cc:16:28: error: invalid conversion from 'const Node*' to 'Node*' [-fpermissive]
current = current->next;
~~~~~~~~~^~~~
prog.cc: In function 'int main()':
prog.cc:25:35: in constexpr expansion of 'getSum(a)'
prog.cc:16:28: error: conversion of 'const Node*' null pointer to 'Node*' is not a constant expression
How should I proceed forward to solve this issue and generate such linked list? Here is Wandbox Link for seeing the execution online.
The immediate error is straightforward to fix:
Node const *current = &n;
// ^^^^^
The complaint is that current = current->next; is assigning a Node const* to a Node *, so don't do that.
Doing that will make your program compile but print 0, because neither push calls modified a. You also can't store the result of push as constexpr since the address of a, an automatic local variable, isn't a constant expression.
You can, however, form a linked list of temporary nodes and immediately use it:
constexpr auto result = getSum(a.push(1).push(22).push(19)); // OK, 42
As #hg_git pointed out in the commentary of your post, a constexpr linked list is not possible.
I cleaned up your code to have a useful error.
#include <iostream>
struct Node
{
constexpr Node(const int n, Node * next = nullptr)
: value(n), next(next) {}
constexpr Node push(const int n) { return Node(n, this); }
int value;
Node * next;
};
constexpr auto getSum(Node n) {
int sum = 0;
Node *current = &n;
while(current != nullptr) {
sum += current->value;
current = current->next;
}
return sum;
}
int main() {
constexpr Node a(0);
a.push(1);
a.push(22);
constexpr auto result = getSum(a);
return result;
}
Giving this
main.cpp: In function 'int main()':
main.cpp:25:13: error: passing 'const Node' as 'this' argument discards qualifiers [-fpermissive]
a.push(1);
^
main.cpp:7:20: note: in call to 'constexpr Node Node::push(int)'
constexpr Node push(const int n) { return Node(n, this); }
^~~~
main.cpp:26:14: error: passing 'const Node' as 'this' argument discards qualifiers [-fpermissive]
a.push(22);
^
main.cpp:7:20: note: in call to 'constexpr Node Node::push(int)'
constexpr Node push(const int n) { return Node(n, this); }
As you can see, even if the keyword const is not there, there is still some problems with const parameters. This comes from the fact that constexpr are calculated at compilation time. Thus making them immutable at run time.
A linked list could change at runtime; if you add or remove a Node per example.
So constexpr are not the right choice in this case.
Edit :
Here's a live demo of your code, clean from constexpr. I added some commentary, feel free to ask if you don't understand a line or a function.

Error when resizing vector of template object

I am trying to create a vector of vector of a template object. The error occurs when I try to resize the inner vector and I can't make heads or tail of the error message. I don't know where it gets the HashTable::Item::Item from. Any suggestions?
/usr/include/c++/4.4.6/bits/stl_vector.h(552): error: no instance of constructor "HashTable::Item::Item [with Key=int, Value=Varvalue]" matches the argument list
resize(size_type __new_size, value_type __x = value_type())
detected during:
instantiation of "void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type={size_t={unsigned long}}, std::vector<_Tp, _Alloc>::value_type) [with _Tp=HashTable<int, Varvalue>::Item, _Alloc=std::allocator<HashTable<int, Varvalue>::Item>]" at line 118 of "main.cc"
Here is the relevant code:
#define VECLEN 16
class Varvalue
{
public:
char data[32];
};
template
class HashTable
{
private:
class Item
{
public:
bool valid;
Key key;
Value value;
Item *next;
Item(const Key k, const Value v, Item *b = 0, bool val = true):
key(k), value(v), next(b), valid(val) {}
};
vector<vector<Item> > table;
int tableSize;
HashTable(const int s): tableSize(s)
{
table.resize(tableSize);
for(int i=0; i<table.size(); i++)
table[i].resize(VECLEN); // <<-- error line 118
}
}
int main()
{
HashTable<int, Varvalue> htable(nkeys);
}
Item doesn't have a default constructor, so you need to provide 2 arguments to resize a vector<Item>. The latter argument shall be a "default" Item with which to fill the vector.
In C++, when you declare a class and you don't provide a constructor a default constructor (without any input parameters) is automatically generated. When you do declare a constructor with input parameters you are not awarded the default constructor. In your case, you did declare a constructor for class item which needs k and v as input parameters but you failed to give them, so either declare a constructor with no input parameters for item or supply k and v.