在模板化类中初始化静态constexpr成员

时间:2018-09-25 08:11:44

标签: c++ c++14

我很惊讶没有在这里找到我的问题的答案。如果我忽略了,可以随时将我指向此处。

编辑:我收到一条通知,说它可能与Why can templates only be implemented in the header file?重复 尽管其中包含许多有关编译器如何处理类模板化类的有用信息,但我仍然找不到有关如何处理类所需的静态常量成员的信息,而这些成员实际上对于所有可能的模板实例化只需要一次。 >

我的用例是到字符串转换类的模板化浮点数。一个成员函数应该是创建带有si前缀的数字的函数。因此,需要一些带有前缀字符的查找数组-该数组与实际选择的任何模板浮点类型无关。我做了这样的事情:

// 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];

尝试实际使用它时,例如转换一个双数,出现以下链接器错误:

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

我在使用Clang的Mac OS上,并启用了C ++ 14进行编译。

问题:我该怎么做?也许可以通过其他方法更好地做到这一点?

1 个答案:

答案 0 :(得分:2)

也许您可以在模板校准之外定义siPrefix。 它不取决于您的模板类型。

您可以直接在cpp文件中定义它,并在cpp文件中使用SIPrefix实现移动方法。