class 的模板特化中的链接器错误

Linker Error in template specialization of a class

这是我的头文件TimeSeries.h,后面是main.cpp

    template<typename>
            struct default_value;    
            template<>
            struct default_value<int> {
               static constexpr int value = 0;
            };

            template<>
            struct default_value<double> {
               static constexpr double value = std::numeric_limits<double>::quiet_NaN();
            };

            template <typename T>
            class TimeSeries
            {
            public:
               std::vector<uint64_t> timeUsSinceMid;
               std::vector<T> values;

               void addValue(uint64_t time, T value)
                {
                 timeUsSinceMid.push_back(time);
                 values.push_back(value);
                }

               TimeSeries<T> * sample(uint64_t sampleFreq, uint64_t startTime=0, uint64_t 
                 endTime=86400*1000*1000ULL)
                {
                 //Some code
                 // I essentially faked a time and a default value push
                  TimeSeries<T>* newSample = new TimeSeries<T>;
                  newSample->timeUsSinceMid.push_back(timeUsSinceMid[0]);
                  newSample->values.push_back(default_value<T>::value);
                  return newSample;
                }
            };

这里是main.cpp:

#include<TimeSeries.h>
int main(int argc, const char * argv[]) {
    TimeSeries<double> T;
    T.addValue(1, 100.0);
    T.addValue(2,200.0);
    T.addValue(3,300.0);
    T.addValue(4,400.0);
    TimeSeries<double>* newT = T.sample(2,1,6);
    //cout<<*newT<<endl;



    return 0;
}

这是链接器错误

Undefined symbols for architecture x86_64:
  "default_value<double>::value", referenced from:
      TimeSeries<double>::sample(unsigned long long, unsigned long long, unsigned long long) in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

谁能解释一下为什么 "default_value::value" 未定义?

查看 this question 的答案。

使用您 posted 代码的结构

您的模板定义定义了对象value,但它仍然需要是declared。 不要问我为什么,我只是从另一个 post 复制@Pete Becker 的回答(不幸的是,它不是很详细)。我所知道的是下面的代码现在可以编译:

template<>
struct default_value<double> {
    static constexpr double value = std::numeric_limits<double>::quiet_NaN();
};
// EDIT: inserted line below
constexpr double default_value<double>::value;

稍微改变一下结构

或者,如果您不想通过大型项目跟踪值声明,您还可以将 values 转换为 in-lined 方法,如下所示:(edit 添加到 constexpr 中;还注意到 inline 不是必需的并且可能不会改变编译器行为)

template<>
struct default_value<int> {
    // EDIT: changed value to function
    static inline constexpr int value() {
        return 0;
    }
};

template<>
struct default_value<double> {
    // EDIT: changed value to function
    static inline constexpr double value() {
        return std::numeric_limits<double>::quiet_NaN();
    }
};

当然,记得将您的 TimeSeries::sample 方法更改为使用 default_value<>::value 作为方法。