2

I'm trying to create a header only library that has a static const value. I need the value to have storage so it can be used, but I'd rather not create a .cpp file since I am trying to make the library header only.

If it is not possible then happy to add a cpp file but still don't know how to define the variable so that storage is allocated.

Below is contrived example of the issue. No surprise it fails with link errors on undefined references. Also tried various combinations of things like static constexpr size_t const &value and static constexpr size_t value but with multiple uses of the header I get multiple definitions at link time

template.h

#pragma once

#include <cstdint>

template<typename T>
struct Data
{
   static const size_t value = sizeof(T) * sizeof(char) + 27;
};

template<>
struct Data<int32_t>
{
   static const size_t value = 9 * sizeof(char) + 27;
};

template<>
struct Data<int64_t>
{
   static const size_t value = 18 * sizeof(char) + 27;
};

main.cpp

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

template<typename T>
void printValue()
{
   // std::cout << "value min=" << std::min(Data<T>::value, 4ul) << std::endl;
   std::cout << "value addr=" << &Data<T>::value << std::endl;
}

int main(int argc, char *argv[])
{
   printValue<int32_t>(); 
   printValue<int64_t>(); 
   printValue<char>(); 
   return 0;
}

Using gcc-9.2

Adrian Cornish
  • 23,227
  • 13
  • 61
  • 77

1 Answers1

4

You declare them all constexpr (instead of const):

template<typename T>
struct Data
{
   static constexpr size_t value = sizeof(T) * sizeof(char) + 27;
};

In C++17, a static constexpr data member is implicitly inline, and thus has storage. There is nothing else you need to do.

Barry
  • 286,269
  • 29
  • 621
  • 977