Aviv Cohn
Aviv Cohn

Reputation: 17183

Initialization of static class member raises "does not name a type" error

Compiling the following code with g++ outputs the following error:

main.cpp:51:19: error: 'running_id' in 'class MyContainer<int>' does not name a type
   51 | MyContainer<int>::running_id = 0;
      |                   ^~~~~~~~~~
main.cpp:11:16: note: 'MyContainer<int>::running_id' declared here
   11 |     static int running_id;
      |                ^~~~~~~~~~

The code:

#include <iostream>
// #include <fstream>
#include <iterator>

using namespace std;


template <typename T>
class MyContainer {
    public:
    static int running_id;

    MyContainer() {
        cout << "Allocating" << endl;
        array = new T[8];
        id = running_id++;
    }

    T& operator[](int index) {
        return array[index];
    }

    ~MyContainer() {
        if (array) {
            cout << "Deallocating" << endl;
            delete[] array;
        }
    }

    MyContainer(const MyContainer& other) {
        cout << "Copy ctor" << endl;
        std::copy(other.array, other.array + 8, array);
    }

    MyContainer& operator=(const MyContainer& other) {
        cout << "operator=" << endl;
        if (this == &other) {
            return *this;
        }
        std::copy(other.array, other.array + 8, array);
        return *this;
    }

    int id{0};

    private:
    T* array = nullptr;
};

MyContainer<int>::running_id = 0;

I have read here on SO that running_id should be declared before it is used. But it doesn't seem to be the problem here, since MyContainer is declared before the line which causes the error.

As an additional question: is there a way to not have to do MyContainer<T>::running_id = 0; for every possible T? The compiler complains if I leave the template argument out.

Upvotes: 0

Views: 445

Answers (2)

catnip
catnip

Reputation: 25388

In C++17 and later, you can declare your class like this:

template <typename T>
class MyContainer {
public:
    static inline int running_id = 0;
    ...

You then don't need the (faulty) MyContainer<int>::running_id = 0; line.

Upvotes: 2

cigien
cigien

Reputation: 60218

You need to define the static member like this:

template <typename T>
int MyContainer<T>::running_id = 0;

now this will work automatically for every T as you want.

Upvotes: 2

Related Questions