
value_initialized has non-deep (shallow?) const semantics. const value_initialized<T> is supposed to be const. Unfortunately, due to compiler errors in VC++ and Borland, it has operator T &() const instead of operator T&() operator const T&() const which breaks const-correctness in a big way. I'd like for there to be a config macro that identifies this error. I would make one, as well as a test for it, myself, but I only have access to icc and gcc on linux, both of which pass the test, so it's hard trying to identify the extent of the overloading selection failure. After creating this macro, we could use it to make a const correct value_initialized class for users with more advanced compilers. For those compilers, I think there would be value to adding operator-> for the invocation of member functions, like boost::optional. As an alternative, deep-copy would break const expectations in generic functions that take a const T &, but it would preserve it elsewhere, so it may be worth some more thought. Finally, I have come up with a similar class (which I wrote with deep const sematics, although I am open to argument about shallow const) for solving the following problem: ---------------------------------------------------------------------- #include <iostream> template<typename T> struct wrap { static const T joe; }; template<typename T> const T wrap<T>::joe; struct call_out { int num; call_out() : num(77) {} }; template<typename T> struct check_call { check_call() { std::cout << wrap<T>::joe.num << std::endl; } }; check_call<call_out> x; int main(){} ----------------------------------------------------------------------- This outputs 0, not 77, on gcc 3.3.2, intel 8, and vc6. I don't know if that's correct, 14.7.1/1 says: "... in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist." If this is std-conforming behavior, or not, i have a workaround that allows: ------------------------------------------------------------------------ #include <iostream> #include "can_init.hpp" template<typename T> struct wrap { static can_init<const T> joe; }; template<typename T> can_init<const T> wrap<T>::joe; struct call_out { int num; call_out() : num(77) {} }; template<typename T> struct check_call { check_call() { wrap<T>::joe.ensure_init(); std::cout << wrap<T>::joe->num << std::endl; } }; check_call<call_out> x; int main(){} ----------------------------------------------------------------------- which obviously uses deep const. Is there any interest in including this in boost/utility/? Should it have shallow or deep const semantics? Jim