boost:any/boost::variant for integral/floating type

Hi,
I am looking at boost::any and boost::variant which seems to be very
usefull additions to C++ for building heterogenous containers.
However in my case I need to build something that would be:
- type safe
- can only contains integral/floating type
- allow operations such as max() / min()
My typical operation on this 'generic_value_type' is simply `+= 1`.
boost::any seems difficult to use, since you need to call any_cast any
time you want to operate on the value.
I am thinking I could just wrap boost::variant inside a custom class,
and add my missing functionalities, something like:
struct AttributeValue
{
private:
struct add_one_visitor
: public boost::static_visitor<>
{
template <typename T>
void operator()(T & i) const
{
i++;
}
};
struct get_min_visitor
: public boost::static_visitor<>
{
template <typename T>
T operator()(T & i) const
{
return std::numeric_limits<T>::min();
}
};
public:
AttributeValue& operator++() {
boost::apply_visitor( add_one_visitor(), Value );
return *this;
}
AttributeValue min() {
return boost::apply_visitor( get_min_visitor(), Value );
}
boost::variant

struct get_min_visitor : public boost::static_visitor<> { template <typename T> T operator()(T & i) const { return std::numeric_limits<T>::min(); } };
You have to pass the result type as an argument to static_visitor template. Maybe you meant something like this: //... AttributeValue(int i) : Value(i) {} AttributeValue(double d) : Value(d) {} // etc... struct get_min_visitor : public boost::static_visitor<AttributeValue> { template <typename T> AttributeValue operator()(const T &) const { return std::numeric_limits<T>::min(); } };

On Tue, Jun 1, 2010 at 3:31 PM, Igor R
struct get_min_visitor : public boost::static_visitor<> { template <typename T> T operator()(T & i) const { return std::numeric_limits<T>::min(); } };
You have to pass the result type as an argument to static_visitor template. Maybe you meant something like this:
//... AttributeValue(int i) : Value(i) {} AttributeValue(double d) : Value(d) {} // etc...
struct get_min_visitor : public boost::static_visitor<AttributeValue> { template <typename T> AttributeValue operator()(const T &) const { return std::numeric_limits<T>::min(); } };
Thanks, I could even get it working with: template <typename T> AttributeValue(T t) : Value(t) {} Thanks -- Mathieu

On 06/01/10 08:12, Mathieu Malaterre wrote:
Hi,
I am looking at boost::any and boost::variant which seems to be very usefull additions to C++ for building heterogenous containers. However in my case I need to build something that would be: - type safe - can only contains integral/floating type [snip] Did I miss anything in boost ? Is boost::variant my best option (when only using fundamental types) ? Look out for the boost:;variant trap revealed by the post:
http://article.gmane.org/gmane.comp.lib.boost.user/58791 The problem occurs when one component can be constructed from another component. as suggested by this quote from the above post:
When bool is added to variant, the statement variant = "hello world" ; calls bool constructor.
I think something similar may happen here, but maybe the problem can be solved by some order of the bound components. Maybe putting more "stringent" components either first or last. That way, maybe the correct one would be selected when the assignment is made.

On Tue, Jun 1, 2010 at 4:42 PM, Larry Evans
On 06/01/10 08:12, Mathieu Malaterre wrote:
Hi,
I am looking at boost::any and boost::variant which seems to be very usefull additions to C++ for building heterogenous containers. However in my case I need to build something that would be: - type safe - can only contains integral/floating type
[snip]
Did I miss anything in boost ? Is boost::variant my best option (when only using fundamental types) ?
Look out for the boost:;variant trap revealed by the post:
http://article.gmane.org/gmane.comp.lib.boost.user/58791
The problem occurs when one component can be constructed from another component. as suggested by this quote from the above post:
When bool is added to variant, the statement variant = "hello world" ; calls bool constructor.
I think something similar may happen here, but maybe the problem can be solved by some order of the bound components. Maybe putting more "stringent" components either first or last. That way, maybe the correct one would be selected when the assignment is made.
Thanks for the warning. My base type are fundamental type, so I should not suffer from this implicit cast. Thanks -- Mathieu

On 06/03/10 04:22, Mathieu Malaterre wrote:
On Tue, Jun 1, 2010 at 4:42 PM, Larry Evans
wrote: [snip] Look out for the boost:;variant trap revealed by the post:
http://article.gmane.org/gmane.comp.lib.boost.user/58791
The problem occurs when one component can be constructed from another component. as suggested by this quote from the above post:
When bool is added to variant, the statement variant = "hello world" ; calls bool constructor.
I think something similar may happen here, but maybe the problem can be solved by some order of the bound components. Maybe putting more "stringent" components either first or last. That way, maybe the correct one would be selected when the assignment is made.
Thanks for the warning. My base type are fundamental type, so I should not suffer from this implicit cast. The 1st attachment, when compiled with gcc4.4 I, gives errors in 2nd attachment.
When the '#if 1' is replaced with '#if 0' it compiles OK, indicating
that you must explicitly cast the argument type to avoid the
ambiguity error in this particular case.
HTH.
-Larry
In file included from /home/evansl/prog_dev/boost-svn/ro/trunk/boost/variant.hpp:17,
from variant_implicit_conversion.cpp:5:
/home/evansl/prog_dev/boost-svn/ro/trunk/boost/variant/variant.hpp: In member function 'void boost::variant
participants (3)
-
Igor R
-
Larry Evans
-
Mathieu Malaterre