在我的应用程序中,我使用一个类来标记由正数表示的元素(参见下面的代码)。 class Stamp
的模板参数通常是一个无符号整数
。用计数器标记的优点是,clear()
通常在巨大的 vector 上执行得很快,因为计数器的一个增量会使所有标记无效。目前,只有在我的单元测试中,我才使用 boolean
作为模板参数。使用 boolean
最接近标记数字的简单实现。但是 boolean
的增量运算符已被弃用,很快就会从标准中消失,编译器已经提示弃用(不知道它提示的部分甚至不会在 的情况下执行 boolean 值
)。对于 boolean
情况,您将如何专门化方法 clear()
?我做错了,我只是通过添加以下定义来尝试。
template<>
void Stamp<bool>::clear() {
std::fill(stamped.begin(), stamped.end(), false);
}
现在编译器提示 clear()
有多个定义。在这种情况下如何正确完成模板特化。在现代 C++ 中,我还有什么其他的可能性来修复这个类?
template <class T> class Stamp {
private:
std::vector<T> stamped;
T stamp;
public:
Stamp(unsigned int size) {
stamped.resize(size, std::numeric_limits<T>::min());
stamp = std::numeric_limits<T>::min();
}
~Stamp() { }
void clear() {
if (stamp < std::numeric_limits<T>::max()) {
stamp++;
}
else {
std::fill(stamped.begin(), stamped.end(), std::numeric_limits<T>::min());
stamp = std::numeric_limits<T>::min() + 1;
}
}
void unset(unsigned int index) {
assert(index < stamped.size());
stamped[index] = std::numeric_limits<T>::min();
}
void set(unsigned int index) {
assert(index < stamped.size());
stamped[index] = stamp;
}
bool isStamped(unsigned int index) const {
return stamped[index] == stamp;
}
};
编辑: 使用 @Constructor 的答案,我可以通过将 clear() 的另一个定义添加到标题中来提出方法特化,如下所示:
template<>
inline void Stamp<bool>::clear() {
std::fill(stamped.begin(), stamped.end(), false);
stamp = true;
}
这有点丑陋,但它确实有效。编译器和测试都不会阻塞它。
最佳答案
完整(或显式)函数模板特化不是模板。所以你应该把它当作一个普通函数来对待。
有两种可能不违反ODR (一个定义规则)当您使用类的函数或方法时:
1) 将函数/方法的声明放在头文件中,将其定义放在某个 cpp 文件中:
// Stamp.h
template<>
void Stamp<bool>::clear();
// Stamp.cpp
template<>
void Stamp<bool>::clear()
{
std::fill(stamped.begin(), stamped.end(), false);
stamp = true;
}
2) 将其标记为 inline
并将其定义放在您的头文件中:
// Stamp.h
template<>
inline void Stamp<bool>::clear()
{
std::fill(stamped.begin(), stamped.end(), false);
stamp = true;
}
关于c++ - 类成员函数的模板特化,以便不在 bool 上使用增量运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47463947/