1

I defined a constructor of Bag class, but compiler gave me an error for the definition. I'm using CLion on Mac. I have no idea what is wrong. I'm thinking it's probably about CLion or compiler problem. Any help would be appreciated!

Here's the error message from compiler

/Users/username/Desktop/projects/bag/Bag.cpp:8:1: error: 'Bag' is not a class, namespace, or enumeration
Bag::Bag() : data{new T[CAPACITY]}, size{0} {}
^
/Users/username/Desktop/projects/bag/Bag.h:15:7: note: 'Bag' declared here
class Bag{

Here's declaration of Bag class which is in 'Bag.h' file.

#ifndef BAG_BAG_H
#define BAG_BAG_H

#include <vector>
#include <cstdlib>
using namespace std;

static const size_t CAPACITY = 100;

template <class T>
class Bag{
public:
    Bag();

    size_t size() const;
    bool empty();
    bool check(const T& item);

    void resize(size_t new_size);
    void clear();
    void remove(const T& item);
    void add(T item);
    void print();

private:
    T* data;
    size_t _size;
};


#endif //BAG_BAG_H

Here's the definitions of Bag class which is in 'Bag.cpp' file.

#include "Bag.h"

template <class T>
Bag::Bag() : data{new T[CAPACITY]}, size{0} {}


... other definitions

Here's main.cpp

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

int main() {
    Bag<int> temp();
    temp().add(1);
    temp().print();

    cout << endl;

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 1
    As Michael points out, this is a template class which means it can't be compiled without knowing the exact type involved. Every `.cpp` file is compiled individually without that context. A template class *must* be header-only. `Bag` does not even exist until you instantiate it in `main.cpp`. – tadman Mar 05 '20 at 18:26
  • @MichaelChourdakis Yes. Thank you. –  Mar 05 '20 at 18:28
  • 1
    @tadman thank you!! –  Mar 05 '20 at 18:30
  • 1
    @tadman "_A template class must be header-only._" - except when explicitly instantiating it for the types you aim to support I guess? – Ted Lyngmo Mar 05 '20 at 18:30
  • 1
    @TedLyngmo The definition can exist in a `.cpp` file if it's not shared, but if you want to share it then it must be completely defined within a header file you `#include`. Think of templates as really fancy macros, a template is effectively a code generator, not a compiled construct, similar to how a macro can't be compiled without using it somewhere in a `.cpp` file. – tadman Mar 05 '20 at 18:33
  • 1
    @tadman Afaik, it's perfectly fine to share it even if the implementation only exists in a `.cpp` file. Think of a class template in a header file (possibly with some SFINAE niceness around) - then explicit instantiation inside the `.cpp` file of every conceivable version that you want to support. It's shared - but limited to the types you explicitly instantiated it for. – Ted Lyngmo Mar 05 '20 at 18:38
  • 1
    @TedLyngmo Not sure how you'd share a definition that's in a `.cpp` file with another `.cpp` file. – tadman Mar 05 '20 at 18:39
  • 1
    Via the header file - you can compile and it'll link just fine – Ted Lyngmo Mar 05 '20 at 18:39
  • 1
    @TedLyngmo I mean if the definition is literally only in a `.cpp` file it can't be shared. If it's in a header file it can. – tadman Mar 05 '20 at 18:40
  • 1
    @tadman Ok, then I misunderstood. I was reacting to "must be header only" and meant to say that it does not need to be header only. It can have the class definition in the header and the implementation in the `.cpp` for supported types - but I think we're on the same page. – Ted Lyngmo Mar 05 '20 at 18:42
  • 2
    @TedLyngmo I mangled the phrasing, so your clarification does help. – tadman Mar 05 '20 at 19:06

1 Answers1

0

You have a template class. So you have to write

template <class T>
Bag<T>::Bag() : data{new T[CAPACITY]}, size{0} {}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335