【发布时间】:2026-01-28 13:50:02
【问题描述】:
我想写一个Settings类来加载和存储各种类型的设置:
template <typename T>
class Setting {
std::string m_name;
T m_defaultValue;
T load() {
if(backend.contains(m_name))
return backend.load<T>(m_name);
return m_defaultValue;
}
void save(const T &value) {
backend.save(m_name, value);
}
}
backend 有一些基本类型的实现,但不是我自己的。所以我需要我的类型的模板专业化。我的想法是创建一个Serializable 类并从中派生我的类:
class Serializable {
public:
virtual std::string serialize() const = 0;
virtual void deserialize(const std::string &data) = 0;
}
现在我需要在 Setting 类中对 load 和 save 进行模板特化,以便在 Serializable 中使用 serialize 和 deserialize 函数:
template<>
void Setting<Serializable>::load()
{
if(backend.contains(m_name)) {
Serializable s;
s.deserialize(backend.load<std::string>(m_name);
return s;
}
return m_defaultValue;
}
template<>
void Setting<Serializable>::save(const Serializable &value)
{
backend.save(m_name, value.serialize());
}
显然这不起作用,因为在Setting<Serializable>::load() 中我无法实例化Serializable s。但是即使我暂时忽略load,它也不起作用,因为它cannot declare field ‘Setting<Serializable>::m_defaultValue’ to be of abstract type ‘Serializable’。
有没有办法为Serializable 的所有子类型编写不同的实现,但仍使用模板参数T?
【问题讨论】:
-
您使用的是哪个版本的 c++?使用 c++17 你可以使用
if constexpr。否则,更好的选择可能是部分模板专业化。但是,您不能只专门化一种方法,您需要专门化整个类。 -
@super 谢谢,它适用于
if constexpr (std::is_convertible_v<T&, Serializable&>)。
标签: c++ template-specialization abstract-base-class