Я расширил QDataStream с помощью оператора преобразования шаблона, чтобы поток данных загружался из самого себя и преобразовывался в любой поддерживаемый тип, как таковой:
class ConvertibleQDataStream : public QDataStream
{
public:
using QDataStream::QDataStream;
template <class T>
explicit operator T ()
{
T t;
*this >> t;
return t;
}
};
И можно добавить поддержку типов, не поддерживаемых QDataStream, перегрузив оператор >> как таковой:
template <class T>
ConvertibleQDataStream&
operator >> (ConvertibleQDataStream& ds, std::vector<T>& v)
{
//Called for std::vector's.
return ds;
}
Идея состоит в том, чтобы иметь возможность создавать конструируемые классы не по умолчанию непосредственно из потока, например:
class Bar
{
public:
Bar(ConvertibleQDataStream&);
};
class Foo
{
int mInt;
std::vector<double> mVector;
Bar mBar;
public:
Foo(ConvertibleQDataStream& ds) :
mInt(ds), //Calls operator >> for int and converts to int
mVector(ds), //Calls operator >> for std::vector<T> and converts to std::vector<T>
mBar(ds) //Plain constructor call
{}
};
Это прекрасно работает, за исключением случаев, когда участник является std::optional
. Конструктор пересылки std::optional
вызывается вместо оператора преобразования шаблона ConvertibleQDataStream
:
template <class T>
ConvertibleQDataStream&
operator >> (ConvertibleQDataStream& ds, std::optional<T>& o)
{
//Never called :(
return ds;
}
class Qux
{
std::optional<Bar> mOptional;
public:
Foo(ConvertibleQDataStream& ds) :
mOptional(ds) //calls Bar::Bar(ConvertibleQDataStream&) rather then operator >> for std::optional<T> due to forwarding c'tor.
{}
};
Можно ли отключить конструктор пересылки std::optional
? Или другой обходной путь для этого.
Foo(ConvertibleQDataStream& ds){ ds >> mOptional; }
? - person alter igel   schedule 24.05.2019ConvertibleQDataStream::operator T()
вызывался сT=std::optional<Bar>
? - person alter igel   schedule 24.05.2019