0

Suppose that I have this code:

// header file

template < std::unsigned_integral size_type = uint32_t >
class Foo
{
public:
    inline static constexpr size_type max { 168 };
};


// source file

// definitions of class's function templates


// call site

template class Foo<uint8_t>;

As you can see, I'm looking for a way to let the user (i.e. the coder) assign an arbitrary value to max when instantiating Foo. For example 255 (the max for uint8_t) etc. Maybe like this:

template class Foo<uint8_t, 255>;

How is this possible? I have also looked at variable templates but I don't know how to make it work in a readable and elegant way.

Also is there a way to separate the static member variable from the class definition and move it to the source file? Because this variable that I'm trying to deal with is related to the implementation of the class and not its interface. I have 4 of these variables and so I don't know how to make it work meanwhile keeping the code readable.

digito_evo
  • 3,216
  • 2
  • 14
  • 42

1 Answers1

3

Your aim is unclear. Do you want something like this, non-type template parameter with a default value?

#include <concepts>
#include <cstdint>
#include <limits>

template <std::unsigned_integral size_type = uint32_t,
          size_type m = std::numeric_limits<size_type>::max()>
class Foo {
 public:
  inline static constexpr size_type max { m };
};

Foo f0;
Foo<uint8_t> f1;
Foo<uint8_t, 127> f2;
static_assert(Foo<uint8_t>::max == Foo<uint8_t, 255>::max);
273K
  • 29,503
  • 10
  • 41
  • 64
  • Yes, this seems like a possible solution. But isn't it bad if I have four of those `m`s in the template parameter list? Also, do you recommend it to move these constants to a cpp file and making them templates? I guess it's not practical though. My goal is to give the user the freedom to initialize these 4 variables with any arbitrary value at the time of instantiating `Foo`. So that each instantiation can have different values for these members. – digito_evo Feb 17 '22 at 21:29
  • 1
    It is not bad, but not very useful, since if you want to assign an arbitrary value to m2, you must assign an arbitrary value to the leading m1. – 273K Feb 17 '22 at 21:33
  • Well, then I better not give them any default values so the user will be forced to type them all. – digito_evo Feb 17 '22 at 21:37
  • Depending on how `Foo` is actually used (and how big a class it is), isn't it going to bloat the code to make these template parameters? Wouldn't it make more sense to make them parameters to the constructor? – Paul Sanders Feb 17 '22 at 23:15
  • @Paul Sanders Yeah they're making the code look more complicated than it really is. But I don't think the approach with constructors would be useful because these static members are `constexpr`. – digito_evo Feb 18 '22 at 08:07
  • Oh yes, sorry, I missed that. But do they actually need to be? – Paul Sanders Feb 18 '22 at 13:36