David Abrahams wrote:
Dirk Schreib [EMAIL PROTECTED] writes:
I would like a variant to be LessThanComparable if all
BoundedTypes are LessThanComparable.
In this example
typedef boost::variantT1, T2, ..., TN V;
V v1 = T1( x );
V v2 = T2( y );
V v3 = T1( z );
v1 v2 should always be true. And v1 v3 should be the same as T1( x )
T1( z ).
I assume that the resulting variant class will be StrictWeaklyComparable
if all
BoundedTypes are StrictWeaklyComparable.
Sounds like maybe you want dynamic_any. Have you looked at Alexander
Nasonov's work?
I would like to emphasize one difference with variant library. User should
_add_ less operation to the list of supported operations to enable
operator. This operator isn't enabled by default. This protects from
undesirable effects because if the user added less I can assume that she
knows what she's doing. But the problem of different order is still
persist.
I think we should coordinate our work on variant and dynamic_any library.
The discussed problem is one point where coordination is needed.
Both libraries work with some set of types by (i) storing value of one
selected type and (ii) calling some operation for stored value. This is
done with some differences, though. In assumption that typedefs for variant
and dynamic_any fixed I can say that:
1. variant operates with _fixed_ set of stored types but with _open_ set of
supported operations (through static_visitor)
2. dynamic_any has _open_ set of stored type but _fixed_ set of supported
operations
There is also some differences in operation support. Variant's operation
looks like:
struct print : static_visitorvoid
{
std::ostream out_;
print(std::ostream out) : out_(out) {}
templateclass T
void operator()(const T value) const
{
out_ value;
}
};
while dynamic_any operation looks like:
struct print : functionprint, void (std::ostream, const anyT)
{
templateclass T
void call(std::ostream out, const T value) const
{
out value;
}
};
On one hand, variant uses operator() which is good for anonymous
operations (obviously, it's not possible for dynamic_any):
variantint, char v(0);
// anonymous function is ok
apply_visitor(v, std::cout _1);
// error, attempt to call std::cout v
for_each(v, v + 1, std::cout _1);
// ok
for_each(v, v + 1, print(std::cout));
On the other hand, dynamic_any has better support for std algorithms,
lambda, bind, etc (well, in variant case it's also possible by binding
apply_visitor):
dynamic_any::anympl::listprint a(0);
// ok, direct call
print()(std::cout, a);
// ok if result of print doesn't contain anyT (void doesn't)
// otherwise, bindR is required
for_each(a, a + 1, bind(print(), std::cout, _1));
Other advantage of dynamic_any is a possibility to mix normal arguments
and anyT-based. Due to nature of dynamic_any it's not possible to call the
operation containing two or more anyT-based arguments for arbitrary
arguments. Call can be made only if all any arguments hold same type or
are derived publicly from one type T stored by one any argument.
However, less works fine with arbitrary types because I added
call_ex/no_call mechanism to the library.
In variant the set of stored types is fixed and all combinations can be
considered (be careful, it may cause combinatorial explosion):
struct plus : variant::functionplus, variantT (variantT, variantT)
{
templateclass T1, class T2
typeof(v1 + v2) call(T1 v1, T2 v2) const
{
// Note that T1 and T2 are in general
// different (in opposite to dynamic_any)
return v1 + v2;
}
templateclass T2
std::string call(std::string v1, T2 v2) const
{
return v1 + lexical_caststd::string(v2);
}
templateclass T1
std::string call(T1 v1, std::string v2) const
{
return lexical_caststd::string(v1) + v2;
}
// ...
};
variantstd::string,int,char s(s);
variantstd::string,int,char i(0);
variantstd::string,int,char s0 = plus()(s, i);
// s2 == std::string(s0)
--
Alexander Nasonov
Remove minus and all between minus and at from my e-mail for timely response
___
Unsubscribe other changes: http://lists.boost.org/mailman/listinfo.cgi/boost