I am working in a graph class , and i have just started to build a class for vertex , and another class for edge , my question is general not related to graph.
first i build a class its name Vertex , i didn't face any problem in implementing it so far , then i started another class its name is Edge , Edge has three main members two of them has the type Vertex , and the third member has the type unsigned int.
here is the code :
#include<iostream>
using namespace std;
class Vertex
{
private:
unsigned int id;
public:
unsigned int get_id(){return id;};
void set_id(unsigned int value) {id = value;};
Vertex(unsigned int init_val) {id = init_val;};
~Vertex() {};
};
class Edge
{
private:
Vertex first_vertex; // a vertex on one side of the edge
Vertex second_vertex; // a vertex on the other side of the edge
unsigned int weight; // the value of the edge ( or its weight )
public:
Edge(Vertex vertex_1, Vertex vertex_2, unsigned int init_weight) //constructor
{
first_vertex(vertex_1.get_id());
second_vertex(vertex_2.get_id());
weight = init_weight;
}
~ Edge(); // destructor
};
///////////////////////////////// this part is to test the result
Vertex ver_list[2] = {7, 9};
Vertex test = 101;
int main()
{
cout<< "Hello, This is a graph"<< endl;
for (unsigned int i = 0; i < 2; i++) cout<< ver_list[i].get_id() << endl;
cout<< test.get_id() << endl;
return 0;
}
before adding the constructor Edge the code was running without errors , after adding the constructor Edge i received errors when trying to run the code , i am not able to determine my mistake above .
Thanks for your suggestions.
here is the errors message i am receiving:
hw2.cpp: In constructor 'Edge::Edge(Vertex, Vertex, unsigned int)':
hw2.cpp:31:6: error: no matching function for call to 'Vertex::Vertex()'
{
^
hw2.cpp:31:6: note: candidates are:
hw2.cpp:13:2: note: Vertex::Vertex(unsigned int)
Vertex(unsigned int init_val) {id = init_val;}; // constructor
^
hw2.cpp:13:2: note: candidate expects 1 argument, 0 provided
hw2.cpp:6:7: note: Vertex::Vertex(const Vertex&)
class Vertex
^
hw2.cpp:6:7: note: candidate expects 1 argument, 0 provided
hw2.cpp:31:6: error: no matching function for call to 'Vertex::Vertex()'
{
^
hw2.cpp:31:6: note: candidates are:
hw2.cpp:13:2: note: Vertex::Vertex(unsigned int)
Vertex(unsigned int init_val) {id = init_val;}; // constructor
^
hw2.cpp:13:2: note: candidate expects 1 argument, 0 provided
hw2.cpp:6:7: note: Vertex::Vertex(const Vertex&)
class Vertex
^
hw2.cpp:6:7: note: candidate expects 1 argument, 0 provided
hw2.cpp:32:41: error: no match for call to '(Vertex) (unsigned int)'
first_vertex(vertex_1.get_id());
^
hw2.cpp:33:42: error: no match for call to '(Vertex) (unsigned int)'
second_vertex(vertex_2.get_id());
Maybe the problem is the syntax in your constructor:
Edge(Vertex vertex_1, Vertex vertex_2, unsigned int init_weight) //constructor
{
first_vertex(vertex_1.get_id());
second_vertex(vertex_2.get_id());
weight = init_weight;
}
You should initialize the members in an initializer list.
Edge(Vertex vertex_1, Vertex vertex_2, unsigned int init_weight) : first_vertex(vertex_1.get_id()), second_vertex(vertex_2.get_id()), weight(init_weight)
{
}
and you should pass const references to Vertex:
Edge(const Vertex& vertex_1, const Vertex& vertex_2, unsigned int init_weight)
hw2.cpp:32:41: error: no match for call to '(Vertex) (unsigned int)'
first_vertex(vertex_1.get_id());
That error message is addressed below:
Edge(const Vertex& vertex_1, const Vertex& vertex_2, unsigned int init_weight) //constructor
: first_vertex(vertex_1.get_id()), second_vertex(vertex_2.get_id()), weight(init_weight)
{
}
You were trying to initialize your vertexes using their constructors inside the Edge constructor's body (instead of in it's initializer list). That is not valid syntax. You would either need to use the initializer list (show, and preferred), or use their assignment operator in the body of the constructor (syntactically correct, but not preferred as the Vertex would be constructed with incorrect data, and then initialized, instead of simply constructed with the correct data).
An even better approach would be to utilize the copy-constructor of Vertex (instead of your conversion constructor):
// notice the lack of calling the get_id function
Edge(const Vertex& vertex_1, const Vertex& vertex_2, unsigned int init_weight)
: first_vertex(vertex_1), second_vertex(vertex_2), weight(init_weight)
{
}
Additionally, with the following error message:
hw2.cpp:31:6: error: no matching function for call to 'Vertex::Vertex()
You have declared a non-default, non-copy-constructor ( Vertex(unsigned int init_val)), so the compiler will not generate a default constructor for you. Since it will try to initialize a Vertex with the default constructor when you attempt to initialize first_vertex and second_vertex in the body of the Edge constructor, and it does not exist, you get an error. You can fix that by declaring a Vertex() {} constructor.
Probably this is the fix:
Edge(Vertex vertex_1, Vertex vertex_2, unsigned int init_weight) //constructor
{
first_vertex = Vertex(vertex_1.get_id());
second_vertex = Vertex(vertex_2.get_id());
weight = init_weight;
}
You are trying to set your vertex values in edge the wrong way. Use something like
first_vertex.set_id(vertex_1.get_id());
Also, there are standard representations for this type of problem. See more here: http://en.wikipedia.org/wiki/Graph_%28abstract_data_type%29#Representations
Related
this is probably a damn straightforward question. But I can't seem to insert my object into a map. I'm pretty sure I do not have to define my own copy constructor, as I solely using standard stuff. Feel like banging my head against a wall now :lol:, this is the map I am trying to create:
map<unsigned, Vertex> vertexes;
Header file of Vertex:
#ifndef KNOTSV2_VERTEX_H
#define KNOTSV2_VERTEX_H
#include <forward_list>
#include <set>
#include <iostream>
#include "VertexType.h"
using namespace std;
// Defines.
typedef tuple<edge_list, edge_list, edge_list> neigh_set_entry;
/*
* Matching
*/
struct match_first {
match_first(unsigned value) : value(value) {};
template<class A>
bool operator()(const pair<unsigned, A> &a) {
return a.first == value;
}
private:
unsigned value;
};
class Vertex {
public:
/*
* Constructors
*/
Vertex(unsigned identifier, VertexType *type, unsigned attributes) : identifier(identifier), type(type), values(attributes_vec(attributes)) {};
// Methods ..
private:
/*
* Members
*/
unsigned identifier;
attributes_vec values;
VertexType *type;
vector<pair<unsigned, neigh_set_entry>> neigh_set;
};
Function i am trying to call:
Vertex& Graph::create_vertex(VertexType &type) {
Vertex v(id_enumerator++, &type, type.num_attributes());
return vertexes[id_enumerator] = v;
}
note: in instantiation of member function 'std::__1::map, std::__1::allocator > >::operator[]' requested here
return vertexes[id_enumerator] = v;
^
note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
class Vertex {
^
note: candidate constructor (the implicit copy constructor) not viable:
note: candidate constructor not viable: requires 3 arguments, but 0 were provided
Vertex(unsigned identifier, VertexType *type, unsigned attributes) : identifier(identifier), type(type), values(attributes_vec(attributes)) {};
So I understand it is due to the fact that it tries to call the 'normal constructor', but I don't want to create getter and setters for the values am passing to the constructor; as they may not be changed. As a second attempt I tried to use map::emplace, but no luck there either. Is there any other option besides creating a normal constructor?
Tried emplace and insert and pairwise construct, no luck either.
Vertex& Graph::create_vertex(VertexType &type) {
//Vertex v();
return vertexes.insert(make_pair(id_enumerator, Vertex(id_enumerator, &type, type.num_attributes()))).first->second;
}
Vertex& Graph::create_vertex(VertexType &type) {
//Vertex v();
return vertexes.emplace(id_enumerator, Vertex(id_enumerator, &type, type.num_attributes())).first->second;
}
Vertex& Graph::create_vertex(VertexType &type) {
//Vertex v();
return vertexes.emplace(piecewise_construct, forward_as_tuple(id_enumerator), forward_as_tuple(id_enumerator, &type, type.num_attributes())).first->second;
}
Read std::map::emplace's documentation:
The constructor of the new element (i.e. std::pair<const Key, T>) is called with exactly the same arguments as supplied to emplace, forwarded via std::forward<Args>(args)....
struct Vertex
{
Vertex(unsigned identifier, int type, unsigned attributes) {}
};
int main()
{
std::map<unsigned, Vertex> vertexes;
// Vertex
// vvvvvvvvvvvvvvvvv
vertexes.emplace(0u, Vertex{0u, 1, 0u});
// ^^
// const unsigned
}
live wandbox example
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.
Shape.h
class Shape {
private:
string name;
public:
Shape(name);
string getName();
void setName(string);
};
Triangle.h
class Triangle: public Shape {
private:
int x;
int y;
public:
Triangle(name,int[3],int[3]);
int getX();
int getY();
void setX(int);
void setY(int);
};
Triangle.cpp
Triangle::Triangle(string name,int _x[],int_y[]):Shape(name) {
x[] = _x[];
y[] = _y[];
}
int Square::getX() {
return x
}
int Square::getY() {
return y;
}
void Square::setX(int _x) {
x = _x;
}
void Square::setY(int _y) {
y = _y;
}
i need to create triangle that takes in name and 3 points of (x,y). when i try to create an array of triangle on the main Triangle Tri[50]; i got the following errors
Triangle::Triangle(std::string,int*,int*)
candidates expects 3 arguments, 0 provided
Triangle::Triangle(const Triangle&)
candidates expects 1 argument, 0 provided
can pls help me check what is wrong with my constructor?? is it because i am creating an array of objects that store arrays of x and y? so i need to use references and pointers for it?
When you create
Triangle Tri[50];
it will try to call the default constructor to initialize those elements in your Tri array, however, you did not provide such a default constructor and you did not call the constructor with 3 parameters, therefore, compiler complains.
Meanwhile, you seems to try to directly initialize one array with another inside the constructor of Triangle:
Triangle::Triangle(string name,int _x[],int_y[]):Shape(name) {
x[] = _x[];//^^I don't understand how this will work in practice.
y[] = _y[];
}
There is no direct assignment on arrays in C++, though C++ std::array (since C++11) has overloaded operator=, but this is not true for regular array.
for some reason I can´t achieve this.
Line::Line(const Pixel &aStart, const Pixel &aEnd){
start = aStart;
end = aEnd;
}
the Line class:
class Line : public Vertex{
public:
Line(const Pixel &start, const Pixel &end);
Pixel getStart();
Pixel getEnd();
private:
Pixel start;
Pixel end;
};
g++ tells me
error: no matching function for call to ‘Pixel::Pixel()’
note: candidates are:
- Pixel::Pixel(int, int, int, int, int)
- Pixel::Pixel(int, int)
- Pixel::Pixel(const Pixel&)//not implemented by me, some sort of default constructor?
I thought actually Im using the last constructor, but something doesnt work. Any help much appreciated.
EDIT: The Pixel Class:
class Pixel{
public:
Pixel(int x, int y);
Pixel(int red, int green, int blue, int x, int y);
void setRed(int red);
void setGreen(int green);
void setBlue(int blue);
void setColor(int r, int g, int b);
int getRed();
int getGreen();
int getBlue();
bool isChanged();
int getX();
int getY();
private:
int red;
int green;
int blue;
int x;
int y;
bool hasBeenChanged;
};
The Line members of type Pixel, start and end, will be default constructed before the constructor of Line runs and sets them to the objects passed in as arguments. It seems that your Pixel class doesn't have a default constructor (because giving any user-defined constructor will stop the compiler from giving you an implicit default constructor). You need to make use of a constructor member initialization list:
Line::Line(const Pixel &aStart, const Pixel &aEnd)
: start(aStart), end(aEnd)
{ }
This initialises start and end with aStart and aEnd respectively, bypassing the default construction that would normally occur.
Because you declare this
Pixel::Pixel(int, int, int, int, int)
Pixel::Pixel(int, int)
the compiler doesn't generate a default constrcutor, or a constructor exists with arguements having default values.
Pixel start;
Pixel end;
These require a default constructor. It doesn't find one, hence the compiler complains. You current code requires the default constructors.
And as a good practice use the initialization list, which wouldn't ask the arguements to default constructed.
Line::Line(const Pixel &aStart, const Pixel &aEnd):start(aStart), end(aEnd){}
I'm trying to compile class A, which has a member of class B, where class B has no default constructor and its only constructor requires multiple arguments. Simple, right? Apparently not...
Class A:
class SessionMediator
{
public:
SessionMediator()
: map_(16,100,100)
{}
Tilemap map_, background_, foreground_;
};
Class B:
struct Tile2D;
class Tilemap
{
public:
Tilemap(const unsigned int tile_size, const unsigned int width,
const unsigned int height)
: tiles_(NULL), tile_size_(tile_size)
{
Resize(width, height);
}
inline void Resize(const unsigned int width, const unsigned int height)
{ /* Allocate tiles & assign to width_, height_... */ }
unsigned int tile_size_, width_, height_;
Tile2D* tiles_;
};
I am instantiating SessionMediator like so:
int main(int argc, char** argv)
{
SessionMediator session;
return 0;
}
This is the error I am getting. I'm compiling in XCode on Mac OS 10.5.8 and the compiler is g++:
session_mediator.h: In constructor 'SessionMediator::SessionMediator()':
session_mediator.h:19: error: no matching function for call to 'Tilemap::Tilemap()'
tilemap.h:31: note: candidates are: Tilemap::Tilemap(unsigned int, unsigned int, unsigned int)
tilemap.h:26: note: Tilemap::Tilemap(const Tilemap&)
session_mediator.h:19: error: no matching function for call to 'Tilemap::Tilemap()'
tilemap.h:31: note: candidates are: Tilemap::Tilemap(unsigned int, unsigned int, unsigned int)
tilemap.h:26: note: Tilemap::Tilemap(const Tilemap&)
(Duplicate of above here)
Build failed (2 errors)
I wrote a short compilable example doing basically the same thing, to try to figure out what exactly I was doing wrong, which compiles just fine with no errors in g++:
class A
{
public:
A(int x, int y, int z)
: x_(x), y_(y), z_(z)
{}
int x_, y_, z_;
};
class B
{
public:
B()
: m_a(1,2,3)
{}
A m_a;
};
int main(int argc, char **argv)
{
B test;
return 0;
}
Why does it fail in the first example? The 3 arg constructor for Tilemap (in Ex#1) is being called in the same way that the 3 arg constructor for A is being called (in Ex#2).
The code seems pretty much identical to me in the two examples.
As I was trying to simplify my example a bit, I accidentally left out two important things: other data members in the SessionMediator class.
The problem was that I had two additional members of the Tilemap class ("background_" and "foreground_"), which weren't being initialized in the constructor initialization list like the first member "map_".
The constructor should be changed to this:
SessionMediator()
: map_(16,100,100), background_(1,1,1), foreground_(1,1,1)
{}
I apologize for any time wasted over this question; it turned out to be something much simpler. Hopefully someone else will see this question and realize the mistake they are making.
The only thing I can think of is if you are using the copy constructor:
SessionMediator a = b; or SessionMediator a (b);
You might get in the situation where the default copy constructor of SessionMediator would try to use the default constructor of Tilemap which will cause the error you have.
Try to put map_(16u,100u,100u) in the SessionMediator constructor call to make the constants unsigned. This is the only thing that comes to mind now :-).
This compiles fine for me:
class Tilemap
{
public:
Tilemap(const unsigned int tile_size, const unsigned int width,
const unsigned int height)
{
}
};
class SessionMediator
{
public:
SessionMediator(): map_(16u,100u,100u){}
Tilemap map_;
};
Well, when you do:
Tilemap map_;
You're calling the default ctor - but you don't have one defined, that's the error message.
On the extra:
Tilemap::Tilemap(const Tilemap&)
C++ generates a ctor that takes a reference for you. So the valid matches are (1) the one you defined which takes 3 args and (2) the auto-generated one that takes the const ref.