gpt4 book ai didi

c++ - 基于方法或自由函数的存在的模板构造函数解析

转载 作者:行者123 更新时间:2023-11-30 03:28:17 25 4
gpt4 key购买 nike

问题

受到 Sean Parent 的启发 "Runtime Polymorphism"我实现了一个 Serializable 类,它使用类型删除来分派(dispatch) Serializable::serialize(...)obj.serialize(...),其中 obj 是一个包装对象。

struct Serializable
{
template <typename T>
Serializable(T obj)
: m_self(std::make_unique<Model<T> >(std::move(obj))) {}

/// Writes itself to a write storage
void serialize(Storage& outStream)
{ return m_self->serialize(outStream); }
private:
struct Concept
{
virtual ~Concept() = default;
virtual void serialize(Storage& outStream) = 0;
};

template <typename T>
class Model final : public Concept
{
public:
Model(T x) : m_data(std::move(x)) {}
private:
void serialize(Storage& outStream) override
{ m_data.serialize(outStream); }
private:
T m_data;
};
private:
std::unique_ptr<Concept> m_self;
};

现在我想用另一个模型类扩展 Serializable,该模型类会将 Serializable::serialize(...) 分派(dispatch)给一个带有 obj< 的自由函数 作为参数:Serializable::serialize(...)serialize(obj, ...)

然后我希望 Serializable 的模板构造函数通过检查 T::serialize(...) 的存在来决定使用哪个模型>序列化(const T&, ...)

问题

是否有可能通过任何方式(例如 SFINAE)自动构造 Serializable,以便它在可能的情况下使用方法序列化,否则使用自由函数序列化?

随意使用任何 C++ 标准,直到 C++17。

最佳答案

您可以设计自己的特征来查明该类是否具有正确的 serialize 成员。有几种方法可以做到这一点,这是其中一种:

template <class T, class = void>
struct HasMemberSerialize : std::false_type
{};

template <class T>
struct HasMemberSerialize<T, std::void_t<decltype(std::declval<T>().serialize(std::declval<Storage&>()))>> : std::true_type
{};

[Live example]

然后,将新的模板参数添加到 Model 并使用 trait 找到它的参数:

struct Serializable
{
template <typename T>
Serializable(T obj)
: m_self(std::make_unique<Model<T, HasMemberSerialize<T>::value> >(std::move(obj))) {}

/// Writes itself to a write storage
void serialize(Storage& outStream)
{ return m_self->serialize(outStream); }
private:
struct Concept
{
virtual ~Concept() = default;
virtual void serialize(Storage& outStream) = 0;
};

template <typename T, bool Member>
class Model;
private:
std::unique_ptr<Concept> m_self;
};

template <typename T>
class Serializable::Model<T, true> final : public Serializable::Concept
{
public:
Model(T x) : m_data(std::move(x)) {}
private:
void serialize(Storage& outStream) override
{ m_data.serialize(outStream); }
private:
T m_data;
};

template <typename T>
class Serializable::Model<T, false> final : public Serializable::Concept
{
public:
Model(T x) : m_data(std::move(x)) {}
private:
void serialize(Storage& outStream) override
{ serialize(m_data, outStream); }
private:
T m_data;
};

关于c++ - 基于方法或自由函数的存在的模板构造函数解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46714526/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com