Reputation: 49
I don't have many experience with templates, but I'm trying to learn on the go, so could someone please tell me what do I do to make this work, because I have seen a lot of examples of using typenames and explicit instantion and explicit specialization but they just include the basic types like int,char,... So please help because I don't understand what to do.
Container.h
#ifndef CONTAINER_H
#define CONTAINER_H
template <typename E>
class Container
{
private:
E element;
public:
Container(E pElement);
virtual ~Container();
};
#endif // CONTAINER_H
Container.cpp
#include "Container.h"
#include "Piece.h"
template class Container<Piece>;
template <typename E>
Container<E>::Container(E pElement) //Error Here;
{
element=pElement;
}
Piece.h
#ifndef PIECE_H
#define PIECE_H
#include <iostream>
#include <string>
using namespace std;
class Piece
{
private:
int x;
int y;
string z;
public:
Piece(int pX,int pY, string pZ);
virtual ~Piece();
};
#endif // PIECE_H
Piece.cpp
#include "Piece.h"
Piece::Piece(int pX, int pY, string pZ){
x=pX;
y=pY;
z=pZ;
}
And the error I'm getting is this:
src\Container.cpp|7|error: no matching function for call to 'Piece::Piece()'|
src\Container.cpp|7|note: candidates are:|
src\Piece.cpp|3|note: Piece::Piece(int, int, std::string)|
src\Piece.cpp|3|note: candidate expects 3 arguments, 0 provided|
include\Piece.h|8|note: Piece::Piece(const Piece&)|
include\Piece.h|8|note: Piece::Piece(const Piece&)|
And I don't know what I'm supposed to do there to make things work. Please help.
Upvotes: 4
Views: 197
Reputation: 3379
You have provided an explicit constructor for Piece
i.e
Piece::Piece(int, int, std::string)
So constructor is not supplying you a default constructor. Now in Container
you are useing the no-arg constructor. That is the reason of the error.
So you need to provide a no-arg (default) constructor for Piece
.
Now if
src\Container.cpp|7|undefined reference to `Piece::Piece()'
is the error message. Then you have defined it in the header file. But there is no body in source file (or somewhere else). So linker can not find it. So add a body to the constructor also.
Upvotes: 1
Reputation: 5233
If you initialize a member in the initialization list in the constructor, then you don't have to provide a default constructor:
template <typename E>
Container<E>::Container(E pElement) : element(pElement)
{
}
In your code, you initialized the member inside the body of the constructor, therefore this meant that element
should first be constructed by the default constructor, and later modified by an assignment operator. And because you didn't provide a default constructor to Piece
, this gave an error.
Upvotes: 2