2
0
mirror of https://github.com/boostorg/convert.git synced 2026-02-17 13:42:18 +00:00
Files
convert/doc/10_default_constructible.qbk
2014-02-16 08:12:51 +11:00

70 lines
2.9 KiB
Plaintext

[section Type Requirements]
In order for a user-defined type to be integrated into the ['boost::lexical_cast] framework:
* TypeOut needs to be ['Copy Constructible];
* TypeOut needs to be ['Default Constructible];
* TypeOut needs to be ['Input Streamable];
* TypeIn needs to be ['Output Streamable].
The first two requirements imposed are by the ['boost::lexical_cast] design and implementation and the last two requirements by the underlying ['std::stringstream] engine.
In turn, the ['Boost.Convert] API facade requires the type to be
* TypeOut needs to be ['Copy Constructible];
* TypeOut needs to be ['Default Constructible] by default.
Additional requirements might be imposed by the respective converter. For example, both mentioned -- ['boost::lexical_cast]-based and ['std::stringstream]-based -- converters require
* TypeIn to be ['Output Streamable];
* TypeOut to be ['Input Streamable].
[endsect]
[section The ['Default Constructible] Type Requirement]
Deeply in the bowels of the implementation a temporary-storage instance of the ['TypeOut] type is created and then populated with the conversion result. The ['boost::lexical_cast] implementation chooses the default constructor to create such an instance. Consequently, the ['TypeOut] type needs to be ['Default Constructible]. For more details see __ref_1__.
['Boost.Convert also creates a temporary-storage instance of the ['TypeOut] type that the respective converter then populates with the conversion result. By default that temporary-storage is created with
namespace boost
{
template<class TypeOut>
TypeOut
convert<TypeOut>::create_storage()
{
return TypeOut();
}
}
and, therefore, the ['Default Constructible] requirement is also the ['default] requirement of the ['Boost.Convert] framework.
A well-designed type (in my opinion, anyway) should only have meaningful and unambiguous constructors... and the default constructor is not always and necessarily one of them. Consider the following ['direction] type as one such example. The type has only two meaningful states and is not ['Default Constructible]:
struct direction
{
enum value_type { up, dn };
direction(value_type value) : value_(value) {}
private: value_type value_;
};
For such a type the call below will not compile (due to the ['Default Constructible] requirement):
direction dir1 = lexical_cast<direction>(str); // Does not compile
direction dir2 = convert<direction>::from(str).value(); // Does not compile
However, ['Boost.Convert] is able to handle such a type with little help from the user. What is needed is the instructions ['how] to create that mentioned temporary-storage:
namespace boost
{
template<> inline direction convert<direction>::create_storage()
{
return direction(direction::up);
}
}
Now the conversion code compiles:
direction dir2 = convert<direction>::from(str).value(); // Compiles
[endsect]