2

In the example given in ยง14.4.1 "Accelerated C++, A. Koenig and B. E. Moo" I have problems if I implement the template specialization like it is presented in the book.

The minimum working example (top down) is:

g++ str.cpp main.cpp

main.cpp:

#include "str.hpp"
 int main(int argc, char** argv)
 {
     Str n;                //def
     return 0;
 }

str.hpp:

#ifndef GUARD_str_h
#define GUARD_str_h

#include <vector> 
#include "ptr.hpp"

class Str {
    public:
        Str(): data(new std::vector<char>) { }
    private:
        Ptr< std::vector<char> > data;
};
#endif

str.cpp:

#include "str.hpp"

ptr.hpp:

#ifndef GUARD_ptr_h
#define GUARD_ptr_h

#include <vector> 

template<class T> T* clone(const T* tp);
template<> std::vector<char>* clone(const 
std::vector<char>* vp);

template <class T> class Ptr {
    public:
        Ptr(): refptr(new size_t(1)), p(0) { }
        Ptr(T* t): refptr(new size_t(1)), p(t) { }
        ~Ptr();
    private:
        T* p;
        size_t* refptr;
};

#include "ptr.cpp"
#endif

ptr.cpp:

template<class T>
Ptr<T>::~Ptr()
{
    if (--*refptr == 0) {
        delete refptr;
        delete p;
    }
}

template<class T>
T* clone(const T* tp)
{
    return tp->clone();
}

template<>
std::vector<char>* clone(const std::vector<char>* vp)
{
    return new std::vector<char>(*vp);
}

The problem is the last template specialization

template<> std::vector<char>*

It gives an

multiple definition of 'std::vector<char...>

error. It only works with

template<> inline std::vector<char>*

1) I do not fully understand why I need "inline".

2) Is this an error in the book? I tried to put this template specialization in the ptr.hpp file. Again, it only works with "inline".

Thanks to all who can put some light on this issue.

Daniel
  • 69
  • 1
  • 2
  • @bolov, seems like a wrong duplicate. This question is about full specializations which actually don't have to be implemented in the header. It seems to me that the main problem in this example is that *.cpp file is included in the header. โ€“ r3mus n0x Dec 30 '19 at 11:26
  • This seems like a better dupe target [When should I write the keyword 'inline' for a function/method?](https://stackoverflow.com/questions/1759300/when-should-i-write-the-keyword-inline-for-a-function-method) โ€“ StoryTeller - Unslander Monica Dec 30 '19 at 11:27
  • There's also [Does it make any sense to use inline keyword with templates?](https://stackoverflow.com/questions/10535667/does-it-make-any-sense-to-use-inline-keyword-with-templates). โ€“ StoryTeller - Unslander Monica Dec 30 '19 at 11:28

1 Answers1

0

Templates are generated compile-time. So if you have this:

template <class T> void func(T t) { /*...*/ }

This - if you use it something like this:

func<int>(5);

the compiler will generate this function:

void func(int t) { /*...*/ }

If you have template class method definitions in a separate source file, it may be compiled separately than the main file. The compiler would not be able to determine what functions to generate. If it's inline, it is basically a macro and it can't be exported to another module.

CoderCharmander
  • 1,862
  • 10
  • 18