1

I'm aware that the following works:

test.h

#pragma once

#include <string>

class testclass
{
private:
    std::string _data;
public:

    template<class T> 
    testclass(const T&);

};

test.cpp

#include "test.h"

template testclass::testclass(const int&);
template testclass::testclass(const long&);

//function can be called only with `int` and `long`
template<class T> 
testclass::testclass(const T &num)
    : _data(std::to_string(num))
{}

So this is a successful way of splitting the declaration and implementation of a template function, but it has some downsides. One of them is having to hardcode all the types with which you want your function to be called and that's a drag. And if the function is quite small, you end up having written more code than you would have if you hadn't templated it...

I was wondering if something like this is possible:

test.cpp

#include "test.h"

template<class T2> //bogus syntax, but here the point of interest
template testclass::testclass(const T2&);

template<class T> 
testclass::testclass(const T &num)
    : _data(std::to_string(num))
{}
DeiDei
  • 10,205
  • 6
  • 55
  • 80
  • How would it work? The .cpp file is compiled with no opportunity to see what types `T` (or `T2`) take in other translation units, but different code needs to be generated for each type. So, it isn't possible to generate any code for the constructor in `test.cpp`, but only where the constructor is _used_ and you know what the type is. – Useless Oct 30 '15 at 12:17

3 Answers3

2

I was wondering if something like this is possible:

No, that's not possible.

Your options are:

  1. Let every user of testclass include the definition.

  2. Define every needed instance of testclass::testclass in the one compilation unit that does include the definition.

There are no other options.

eerorika
  • 232,697
  • 12
  • 197
  • 326
0

Why don't you use template on your class directly in your .h ?

#pragma once

#include <string>

template <T>
class testclass
{
private:
    std::string _data;
public:

    testclass(const T& num) : data(std::to_string(num)) {}

};

This way, you can use your class with any type you want, for example :

testclass<int> test(1);
testclass<double> test(2.0);
...
dkg
  • 1,775
  • 14
  • 34
  • Because I'm trying to avoid that. Plus it eliminates the possibility to separate the implementation in a .cpp file. – DeiDei Oct 30 '15 at 12:13
0

I suppose that it's not possible, because on compilation stage your compiler can see only your test.cpp file and has no idea about for which types it must instantiate this template.

So, if you want to split template to h/cpp files just for modularity purpose, you can try the following trick:

  1. rename your "test.cpp" file to "test.tpp"(*.tpp extension just shows that it's template class' definition here)
  2. leave *.h file as is, but add #include "test.tpp" statement to the end.

and possibly you must move out your includes from *.tpp to the head of test.h, but I'm not sure, just play with it.

Valery Shevchuk
  • 411
  • 2
  • 9