0

Im trying to convert the following header file into a seperate header and .cpp file.

    template <class T>
class Rolodex {
  public:
    /**
     * Creates a new empty Rolodex
     */
    Rolodex()
    {
        sentinel_ = new Item;
        sentinel_->value_ = T();
        sentinel_->next_  = sentinel_;
        sentinel_->prev_  = sentinel_;
        current_ = sentinel_;
    }

    ~Rolodex()
    {
        while (current_ != sentinel_) {
            delete_current();
        }
        delete sentinel_;
    }

    /**
     * Returns true if the Rolodex is positioned at the beginning.
     */
    bool is_before_first()
    {
        return current_ == sentinel_;
    }

    /**
     * Returns true if the Rolodex is positioned at the end.
     */
    bool is_after_last()
    {
        return current_ == sentinel_;
    }

    /**
     * Rotates the Rolodex one step forwards.
     */
    void rotate_forward()
    {
        current_ = current_->next_;
    }

    /**
     * Rotates the Rolodex one step backwards.
     */
    void rotate_backward()
    {
        current_ = current_->prev_;
    }

    /**
     * Returns the value of the current card.
     */
    const T &current_value()
    {
        return current_->value_;
    }

    /**
     * Inserts a new item after the current position and
     * positions the Rolodex at the newly inserted item.
     */
    void insert_after_current(const T &value)
    {
        Item *coming = new Item;
        coming->value_ = value;
        coming->next_  = current_->next_;
        coming->prev_  = current_;

        current_->next_->prev_ = coming;
        current_->next_ = coming;

        current_ = coming;
    }

    /**
     * Inserts a new item before the current position and
     * positions the Rolodex at the newly inserted item.
     */
    void insert_before_current(const T &value)
    {
        Item *coming = new Item;
        coming->value_ = value;
        coming->prev_  = current_->prev_;
        coming->next_  = current_;

        current_->prev_->next_ = coming;
        current_->prev_ = coming;

        current_ = coming;
    }

    /**
     * Deletes current item and positions the Rolodex
     * at the _following_ item
     */
    void delete_current()
    {
        Item *going = current_;
        current_->prev_->next_ = current_->next_;
        current_->next_->prev_ = current_->prev_;

        if (going->next_ == sentinel_)
            current_ = going->prev_;
        else
            current_ = going->next_;

        delete going;
    }

  private:
    struct Item {
        T value_;
        Item *next_;
        Item *prev_;
    };

    Item *sentinel_;
    Item *current_;
};

#endif /* ROLODEX_H_ */

However when i split them apart, if i don't include

template <class T>

in the header file i get an error trying to declare

T value;

but if i do i get multiple errors in the .cpp file saying Rolodex is not a file class or enumeration. Is there a different type I can use to declare my value; and if so how do i go about modifying the code to fit this. Any help is greatly appreciated im super lost

EDIT: Thank you all for your help, my understanding of the C++ classes was lacking and after some research on the similar threads you provided I fixed my issue.

11
  • 2
    You cannot define templates in a .cpp file, all templates should be available during compilation, i.e. they have to be completely included by #include "foo.h", and for that they have to be in a header file Commented Jun 11, 2020 at 8:30
  • 1
    Does this answer your question? Storing C++ template function definitions in a .CPP file Commented Jun 11, 2020 at 8:32
  • @AlexLarionov does this mean my code would require a complete rework. For example i have the following Rolodex::Rolodex() { { sentinel_ = new Item; sentinel_->value_ = T(); sentinel_->next_ = sentinel_; sentinel_->prev_ = sentinel_; current_ = sentinel_; }. How do i go about removing use of T(); Commented Jun 11, 2020 at 8:33
  • You don't remove it, you move every definition for functions of class Rolodex in the header. Once there, it should work Commented Jun 11, 2020 at 8:42
  • 2
    Simply follow to the duplicate and read the linked articles. It makes not much sense to repeat all this stuff here again. The question, why and how template code can (not) be moved to cpp files is fully discussed and explained. So I hope the question will be closed as all answers are available. If you have a sepcific / detailed question to an aspect of all that, feel free to ask again! Commented Jun 11, 2020 at 8:57

2 Answers 2

3

If you don't know how the templates work, I would suggest reading the topic first.

You can define the template class members in a separate .cpp file, but you will also have to instantiate a class for all of the types you will be using. You can do such declaring a simple dummy object in the .h or .cpp file.

// tmpl.h

template <typename T>
struct S {
  S();
  T _a_field;
}

// tmpl.cpp

template <typename T>
S<T>::S() {}

S<int> dummy;

However, this is not a suggested approach. I personally would suggest defining all in a single tmpl.h file or in another file and include it into tmpl.h

Sign up to request clarification or add additional context in comments.

Comments

-1

when using templates the complete implementation needs to be in the header. You cannot use .cpp files for the method definitions, but if you would still like to separate interface and implementation. You can use .hpp for the class definition, .inl file for the method definitions. At the end of the .hpp file, you have to include the .inl file containing that implementation. You can learn more here, why template codes cannot be moved to .cpp file https://youtu.be/6wdCqNlnMjo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.