0

I would like define my template specialization in the .cpp file and not in .h file. Is there a way I can do this? I am using the g++ compiler

//main.cpp

#include <iostream>
#include <string>
#include "People.cpp"
using  namespace std;

int main() {
  
  Spunky <int> obj3(1);
  Spunky<char>obj2('y');
  return 0;
}

//People.cpp

#include <iostream>
#include "People.h"


using namespace std;

// TEMPLATE SPECIALISATION
template < class T>

Spunky <T>:: Spunky( T x){
  cout << x << " is not a character ! " << endl;

}

template <>
Spunky:: Spunky<char> ( char x ) {

  cout << x << " is indeed a character"<< endl;
}



//People.h

#ifndef PEOPLE_H
#define PEOPLE_H
using namespace std;

// TEMPLATE SPECIALISATIONS
template < class T>
class Spunky{
 public:
  Spunky ( T x) ;
};

template <>
class Spunky <char> {
 public:
  Spunky (char x);
    //  {  cout<< x << "is indeed a character"<<endl; }

};

#endif

compiler error is:

template argument deduction is only available with -stdC==1z or -std=gnu++1z

How can I go about fixing this?

Geno C
  • 1,401
  • 3
  • 11
  • 26
  • Not your question but, if you write your template code in a .cpp file, but then include the .cpp file like a header file, how exactly is that different from doing the normal thing and writing the code in a header file? – john Jul 16 '20 at 06:39
  • Do you add -stdC==1z or -std=gnu++1z as arguments to your Compiler? – SebastianH Jul 16 '20 at 06:58
  • I think if you use the new C++ modules feature. Otherwise template specialization needs to be visible to same translation unit where it is used so compiler can generate the code. (i.e. you need to #include like comment above says) – Hitobat Jul 16 '20 at 07:00

1 Answers1

1
template <>
Spunky:: Spunky<char> ( char x ) {

  cout << x << " is indeed a character"<< endl;
}

Is not the correct syntax for defining the implementation of a member method. Spunky:: Spunky<char> is the syntax for defining a method which itself is templated not a templated class, the correct syntax is Spunky<char>::Spunky.

You also don't specify template <> when defining template member specialisations.

The full definition should therefore be:

inline Spunky<char>::Spunky( char x ) {
  cout << x << " is indeed a character"<< endl;
}

I recommend you don't include .cpp files, if you want to split your template implementation into 2 files then give it a different extension (some use ipp).

The normal rules for header files apply to anything you #include so using namespace std is a really bad idea many recommend not using using namespace std at all.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Unfortunately this does not work. The error is: ```People.o: In function `Spunky::Spunky(char)': People.cpp:(.text+0x0): multiple definition of `Spunky::Spunky(char)' main.o:main.cpp:(.text+0x0): first defined here People.o: In function `Spunky::Spunky(char)': People.cpp:(.text+0x0): multiple definition of `Spunky::Spunky(char)' main.o:main.cpp:(.text+0x0): first defined here collect2: error: ld returned 1 exit status ./ex: line 4: ./exe: No such file or directory rm: cannot remove 'exe': No such file or directory``` – stanley Jul 17 '20 at 04:51
  • If you're still #including your cpp file you need to make the functions `inline` – Alan Birtles Jul 17 '20 at 06:27