4

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.

  • If you're going to use it at all, surely do not put a `using namespace std;` in a header file. – James Adkison Mar 24 '16 at 06:31
  • add default contructor of Piece, (add new constructor or add default values for variables to existing one). Also looks like you forgot about desctructor implementation – jonezq Mar 24 '16 at 06:31
  • As @jonezq states you need to add a default constructor, see [What are all the member-functions created by compiler for a class? Does that happen all the time?](http://stackoverflow.com/questions/3734247/what-are-all-the-member-functions-created-by-compiler-for-a-class-does-that-hap). – James Adkison Mar 24 '16 at 06:34

2 Answers2

2

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.

Adi Levin
  • 5,165
  • 1
  • 17
  • 26
1

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.

deeiip
  • 3,319
  • 2
  • 22
  • 33
  • Thats because you need a body for destructor also. Just defining in header won't work. Because linker won't find what code to execute the the function is called. If you are defining a function explicitly and calling it elsewhere. You need a body. – deeiip Mar 24 '16 at 06:46