0

The following code works fine, when my template class is defined inline:

main
{
   unsigned int A=0;                       //local variable in  'main'.
   Test<int>  TestObjekt;   //Object.
   //do something
   cout<<TestObjekt.calculate_a(A);
};

The Class is just made 4 test reasons and it adds a '2' to the given data 'a' and it returns the result the local variable 'A' of main:

template <typename T> class Test        //dichiarazione classe
{
private: 
     T a;      //private variable of changeable type T.

public:               
  Test(T InitA)     //constructor
  {
     a=InitA;
  }

  T calculate_a(T a)  //method
  {
     a+=2;
     return a;
  }
};

In this way, everything works fine, but when I make an outline definition of the class, the compiler doesn't accept it anymore. Here is the decleration:

template <typename T> class Test        //class declaration
{
private: 
  T a;      //private variable

public:               
  Test(T InitA);  //constructor
  T calculate_a(T);  //method
};

Now my Definitions:

template <typename T>  Test<T>::Test(T InitA)
{
   a=InitA;
}

template <typename T> T Test<T>::calculate_a(T)  //metodo della classe Test
{
   a+=2;
   return a;
}

The error messages are the following:

1.error C2512: 'Test<T>': non è disponibile alcun costruttore predefinito...  
  means: there is no appropriate, predefined constructor available

1>        with
1>        [
1>            T=int
1>        ]

I'm using the Visual C++ 2008 Express Version Compiler. I'm a C++ beginner and I've neaerly had a nervous breakdown, because I'm already fighting a long time to make the program run.

Hope somebody could help me

Thanks and regards

Uwe

Salgar
  • 7,687
  • 1
  • 25
  • 39
Uwe_98
  • 697
  • 1
  • 8
  • 21
  • Why you don't follow the working way? – Balog Pal Jun 04 '13 at 11:17
  • You define a constructor taking a `T`. Therefore you need to provide a `T` when you create an instance. So do `Test TestObjekt(A);`. – BoBTFish Jun 04 '13 at 11:19
  • 1
    The code you're showing is not the code you're compiling, please fix your question to be more accurate. – Jonathan Wakely Jun 04 '13 at 11:51
  • @billz: the decleration is in MyDefinitions.h, and the definition in MyDefinitions.cpp, which is apart from the main file. But other subroutines and classes are seperated in the same way in this program and the work fine. thanks – Uwe_98 Jun 04 '13 at 11:58
  • @Balog Pal: What do You mean by 'working way'? – Uwe_98 Jun 04 '13 at 12:06
  • @BoBTFish: I've tried so, but it gives me another error message. , what means: 2 external not resolved. It seams to me a link error. But ok, I'll make a test: I will still define the class outline, but in the mainfile. I'll inform You what happens then. – Uwe_98 Jun 04 '13 at 12:09
  • @JonathanWakely: Yes You're right. Sorry. I wrote it into a much larger project in order to test the tecnique. I cannot post the whole program, but if You compile it like this, it should run. – Uwe_98 Jun 04 '13 at 12:12
  • @Uwe_98, you cannot compile templates separately, they must be visible in header files. – Jonathan Wakely Jun 04 '13 at 12:17
  • The one said "The following code works fine". After discarding export we better accept that templates are meant for the inclusion model. It's possible to tweak some cases keeping them extern and force specific instantion but that kills most of their convenience. And is too rarely balanced. – Balog Pal Jun 04 '13 at 12:33
  • @BoBTFish: Now it works fine. Have You got an' explanation? Cheers Uwe – Uwe_98 Jun 04 '13 at 12:44
  • @BalogPal and all the others: Yes, You're right! I made some tests. The results are: All in mainfile (declaration and definition), only declaration in headerfile or all in headerfile works fine. Declaration in headerfile (MyDefinitions.h) and Definition in external sourcefile (MyDefinitions.cpp) does not work. Thanks 4 Your help. Uwe_98 – Uwe_98 Jun 04 '13 at 13:27

2 Answers2

1

In your main function, where an Test object is made, add a value to the constructor (make the TestObject with init-value):

Test<int>  TestObjekt(0);   // Object with init value

or make a constructor that doesn't require a value, e.g. in your class declaration add a default value to the prototype of the constructor:

Test(T InitA= 0);  //constructor with default value

Full version:

template <typename T> class Test        //class declaration
{
    private: T a;      //private variable

    public:               
        Test(T InitA= 0);  // <<<-- either change here
        T calculate_a(T);  //method
};

Or change main:

void main()
{
    unsigned int A=0;             //local variable in  'main'.

    Test<int>  TestObjekt(0);   // <<<--- change here.

    //do something
    printf("%d", TestObjekt.calculate_a(A));
};
Nicholaz
  • 1,419
  • 9
  • 11
  • :Hi Nicholaz, unfortunately not. It doesn't change anything of the error message. The 'error pointer'(I don't know, if the expression is right), points to the definition of the object in main, -->Test TestObjekt; Thanks for the effort. Uwe – Uwe_98 Jun 04 '13 at 11:28
  • 2
    Yes it does. I did even compile this here and got the same error. Adding "(0)" to TestObjekt did make it go away (and it is not in your sample). – Nicholaz Jun 04 '13 at 11:30
1

The line Test<int> TestObjekt; is implicitly calling the default constructor Test<int>() which doesn't exist.

You either need to add arguments to your constructor call in your main: Test<int> TestObjekt(0);

Or, alternatively, define a constructor that doesn't require a value Test(){ \\do something }


Also the template definitions must be in the header file.

See this answer for a good explanation of why the definitions are required in the header.

Community
  • 1
  • 1
Panda
  • 1,231
  • 18
  • 27
  • 1
    No it should not. He's making a parameter-less definition of an object, but the class requires a parameter to the constructor. – Nicholaz Jun 04 '13 at 11:36