PluginPenguin
PluginPenguin

Reputation: 1930

Initialize a static constexpr member in templated class

I'm surprised to not have found an answer to my question here already. If I overlooked it feel free to point me there.

Edit: I got a notification that this could be a possible duplicate of Why can templates only be implemented in the header file? While this contains a lot of helpful information on how classes templated classes are treated by the compiler I still don't find information on how to treat static constant members needed by the class that are actually only needed once for all possible template instantiations.

My use-case is a templated floating point number to string conversion class. One member function should be a function that creates numbers appended with si-prefixes. Therefore some lookup array with the prefix characters is needed - this array is unrelated to whichever templated floating point type is actually chosen. I did something like that:

// Float2String.h
#include <string>

template <typename FloatType>
class Float2String 
{

public:

    //...

    static std::string withSIPrefix (FloatType floatNumber, int numSignificantDigits)
    {
         // scale the number, convert it to a string and compute the idx to pick the right prefix...

         return floatNumberScaledAndConvertedToString + siPrefixes[idx];
    }

private:
    static constexpr char[11][3] siPrefixes = {"f", "p", "n", "μ", "m", "", "k", "M", "G", "T", "P"};
};

// Float2String.cpp
#include "Float2String.h"

template <typename FloatType>
constexpr char Float2String<FloatType>::siPrefixes[11][3];

When trying to actually use it e.g. to convert a double number, I get the following linker error:

Error:Undefined symbol 'Float2String<double>::siPrefixes' referenced from:
Error:  Float2String<double>::withSIPrefix(double, int) in Main.o

I'm on Mac OS with Clang and compile with C++ 14 enabled.

Questions: How do I do it right? And maybe could this be done better with a different approach?

Upvotes: 0

Views: 1120

Answers (1)

Gojita
Gojita

Reputation: 500

Perhaps you can define your siPrefixes outside the template calss. It does not depend on your template type.

You can define it directly in your cpp file and move method withSIPrefix implementation in your cpp file also.

Upvotes: 2

Related Questions