Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining templated functions in .cpp from .h (getting error)

Tags:

c++

Part of the header file dlist.h is defined as:

#ifndef __DLIST_H__
#define __DLIST_H__
#include <iostream>

class emptyList {};

template <typename T>
class Dlist {
 public:
    bool isEmpty() const;

 private:
    struct node {
    node   *next;
    node   *prev;
    T      *o;
    };

    node   *first; // The pointer to the first node (NULL if none)
    node   *last;  // The pointer to the last node (NULL if none)
};

#include "dlist.cpp"
#endif

When I create a dlist.cpp file like this:

#include "dlist.h"

template <typename T>
bool Dlist<T>::isEmpty() const
{
    return !first and !last;
}

I get the error message at line 4: redefinition of 'bool Dlist::isEmpty() const'

If I remove the #include "dlist.h" I get the error at line 4: expected initializer before '<' token

Any help here? Is there something I'm doing wrong that's not allowing me to just define my functions from the dlist.h file? Thank you.

like image 948
Bob John Avatar asked Aug 06 '26 11:08

Bob John


2 Answers

You have to put the implementation of the class template's member functions in the header file or in a file included by the header. The compiler needs access to this code in order to instantiate templates for any given type T.

In your case, the problem seems to be that you are including the header in the .cpp and vice versa. If you really want to keep declaration and implementation in separate files, I suggest changing the implementation's suffix from .cpp to something else, e.g. .icpp. Some build systems might try to compile an object file out of anything with a .cpp suffix, and this would also result in error.

  1. Remove #include "dlist.h" from dlist.cpp.
  2. (optional) rename dlist.cpp to something like dlist.icpp. Why? Because many build systems automatically compile any file ending in .cpp into an object file. And many programmers assume that a .cpp file will be compiled into an object file.
  3. (only if step 2 taken) include the re-named dlist.icpp in dlist.h, as is currently done for dlis.cpp.
like image 80
juanchopanza Avatar answered Aug 08 '26 00:08

juanchopanza


The header file is defined for me, I'm not allowed to change it in any way

Then you'll need to remove the #include "dlist.h" directive from the .cpp (because you're already in dlist.h, and thus creating a cyclic dependency), thus making everything completely backwards, because the header you were given is fscking stupid!

A .cpp should never be #included. Typically, if one must split template-related definitions into their own file, it should have some other extension. I strongly recommend you talk to the person who has emplaced this mandate on you and explain that their header is silly, confusing and non-conventional.

like image 45
Lightness Races in Orbit Avatar answered Aug 08 '26 00:08

Lightness Races in Orbit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!