class 的模板特化中的链接器错误
Linker Error in template specialization of a class
- 我有一个头文件 TimeSeries.h,其中包含 default_value 模板
的定义和特化
- TimeSeries class 还有其他方法
- 我在 main.cpp
中包含了 TimeSeries.h 文件
这是我的头文件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;
稍微改变一下结构
或者,如果您不想通过大型项目跟踪值声明,您还可以将 value
s 转换为 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
作为方法。
- 我有一个头文件 TimeSeries.h,其中包含 default_value 模板 的定义和特化
- TimeSeries class 还有其他方法
- 我在 main.cpp 中包含了 TimeSeries.h 文件
这是我的头文件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;
稍微改变一下结构
或者,如果您不想通过大型项目跟踪值声明,您还可以将 value
s 转换为 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
作为方法。