【发布时间】:2016-09-13 09:16:01
【问题描述】:
我想编写一个通用序列化库,它提供例如一个通用的save 函数。
该库包含自定义类型特征,例如some_condition:
template <typename T>
struct some_condition
{
constexpr static bool value = std::is_same<std::string, T>::value ||std::is_arithmetic<T>::value ;
};
save的行为是根据some_condition选择的:
template <typename T>
std::enable_if_t<some_condition<T>::value> save(const T& value)
{
std::cout << "these types will be handled in a specific way: " << value << std::endl;
}
template <typename T>
std::enable_if_t<!some_condition<T>::value> save(const T& value)
{
std::cout << "these types will be handled in another way: " << value << std::endl;
}
save 应该可以为用户数据类型定制,不仅通过重载,而且通常通过特征。
因此我创建了trait_extension,它可以专门用于特征模板:
template <template<typename> class Trait, typename T>
struct trait_extension : Trait<T>
{
}
save 必须相应修改:
template <typename T>
std::enable_if_t<trait_extension<some_condition,T>::value> save(const T& value) { ... }
template <typename T>
std::enable_if_t<!trait_extension<some_condition,T>::value> save(const T& value) { ... }
用户现在可以提供自己的专业化trait_extension:
template <typename T>
struct trait_extension<some_condition, T>
{
// user specific extension: exclude floats from condition
constexpr static bool value = !std::is_floating_point<T>::value && some_condition<T>::value;
};
我的问题::
有没有“更好”/更优雅的方式来实现可扩展的特征?
【问题讨论】:
-
如果有一个“一般情况”,其中 is_string 被定义为 false,并且专门定义任何被认为是字符串的东西,难道不是更简单吗?
-
你看过C++ Container Pretty-Printer作为参考吗?
-
"但是,这只有在
trait_extension特化存在于print之前才有效。"嗯? -
@ildjarn
print与实际功能不同,这只是一个示例;我正在寻找如何实现可扩展特征的建议,我在 cxx-prettyprint 中没有找到任何参考 -
@T.C.奇怪,当我昨天尝试时,
trait_extension的位置(print的上方/下方)似乎很重要……再试一次,now it works;不过,关于如何实现可扩展性功能,还有什么“更好”/更优雅的方法吗?
标签: c++ templates c++14 typetraits