我有一個ISerializable純虛擬read和write函式的介面。我也有一List<T>堂課。所以,我的問題是:我可以繼承我List<T>的ISerializable只有如果T也繼承自ISerializable?
用法示例:
#include <array>
#include <iostream>
class ISerializable
{
public:
virtual void read(std::istream& stream) = 0;
virtual void write(std::ostream& stream) = 0;
};
class A : public ISerializable {
public:
void read(std::istream& stream) override {}
void write(std::ostream& stream) override {}
};
class B {};
template<typename T>
class List : public ISerializable
{
public:
void read(std::istream& stream) override
{
for (int i = 0; i < items.size(); i )
{
items[i].read(stream);
}
}
void write(std::ostream& stream) override
{
for (int i = 0; i < items.size(); i )
{
items[i].write(stream);
}
}
private:
std::array<T, 10> items;
};
int main()
{
List<A> list_a;
//List<B> list_b; <- error here
}
uj5u.com熱心網友回復:
您確實可以在 C 20 中設定類似的東西。
template<typename T>
class List : public ListCommon<T> {
};
template<std::derived_from<ISerializable> S>
class List<S> : public ListCommon<S>, public ISerializable {
// Implement the serialization
};
可序列化型別的特化只有在派生型別的附加約束下才可行ISerializable(使用標準std::derived_from概念檢查)。
ListCommon 是我放置常見實作細節的地方,以避免在專業化時重復它們。
uj5u.com熱心網友回復:
好的,如果您已經有很多不想重構和/或復制的類,則此解決方案適合。這里的缺點是 IDE 有時無法為您提供幫助。但是,由于它暗示了概念的主要特征之一,它仍然是合法的。小心點!
在這里,我們有一個明確要求實作某些功能的介面和一個也需要實作相同功能的概念。更喜歡界面而不是概念!如果您繼承介面,IDE 將協助您進行函式多載。如果您想稍后將介面用作引數型別,則需要概念(參見實用程式類示例)。這是鴨子打字的一個例子。
class ISerializable
{
public:
virtual void write_to_stream(std::ostream& stream) const = 0;
virtual void read_from_stream(std::istream& stream) = 0;
};
template<typename T>
concept ImplicitlySerializable = requires(const T a1, T a2, std::ostream os, std::istream is)
{
a1.write_to_stream(os);
a2.read_from_stream(is);
};
template<typename T>
concept Serializable = std::derived_from<T, ISerializable> || ImplicitlySerializable<T>;
一些實用函式來處理任何匹配概念的物件
class StreamUtils
{
public:
template<Serializable T>
static void write(std::ostream& stream, const T& value)
{
value.write_to_stream(stream);
}
template<Serializable T>
static void read(std::istream& stream, T& to)
{
to.read_from_stream(stream);
}
};
使用示例:
// Interface usage
class Animal : public ISerializable
{
void write_to_stream(std::ostream& stream) override
{
// serialization code here
}
void read_from_stream(std::istream& stream) override
{
// deserialization code here
}
}
// Concept usage
template<typename T>
class List
{
void write_to_stream(std::ostream& stream) const requires Serializable<T>
{
// serialization code here
}
void read_from_stream(std::istream& stream) requires Serializable<T>
{
// deserialization code here
}
{
int main()
{
std::ofstream file("my_file.bin", std::ios::out | std::ios:binary);
StreamUtils::write(file, Animal());
StreamUtils::write(file, List<Animal>());
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/417001.html
標籤:
