Archduke
Archduke

Reputation: 349

Static constexpr member of a template class different for each instance?

I was under the impression that static members of a class share their value between all instances of that class. My understanding seems to be lacking though, perhaps because of the inclusion of templates or constexpr in this example:

#include <iostream>
#include <array>

template <typename T, std::size_t maxSize>
class Foo
{
public:
    unsigned int getLen() {
        return containerLen;
    }
    
private:
    static constexpr std::size_t containerLen = maxSize + 1;
    std::array<T, containerLen> arr;
};

int main()
{
    Foo<int, 10> foo1;
    std::cout << foo1.getLen() << std::endl;
    
    Foo<int, 12> foo2;
    std::cout << foo2.getLen() << std::endl;
    std::cout << foo1.getLen() << std::endl;

    return 0;
}

Which gives the following output:

    11
    13
    11

I'm probably missing something obvious, but what is it that allows each instance of Foo to have a different value of containerLen?

Upvotes: 3

Views: 202

Answers (2)

max66
max66

Reputation: 66190

Your error is consider Foo a class.

It's a class template, so Foo<int, 10> and Foo<int, 12> are different classes.

So there is a containerLen for Foo<int, 10> and a different containerLen for Foo<int, 12>.

If you want a common static member for all class templates, you can insert it in a common base class.

The following is a simple example

#include <iostream>

struct Foo
 { static int value; };

int Foo::value = 0u;

template <typename T>
struct Bar : public Foo // <-- all Bar classes inherit the same value
{ };

int main()
 {
   Bar<int>  bi;
   Bar<long> bl;

   bi.value = 10;
   bl.value ++;

   std::cout << bi.value << std::endl; // print 11
   std::cout << bl.value << std::endl; // print 11
 }

Upvotes: 4

Adrian Mole
Adrian Mole

Reputation: 51815

Foo<int, 10> and Foo<int, 12> are different classes - they just share the same template. All instances of Foo<int, 10> will share the same containerLen, as will all instances of Foo<int, 12>; but the two classes will not share a common value.

Upvotes: 9

Related Questions