
David Abrahams wrote:
Actually, now that I look at this, it seems Boost.Parameter is still using the "bad-old-method" of initializing these things. IIRC we decided that to avoid order-of-initialization problems /and/ ODR one needs a reference declared in an unnamed namespace, and initialized directly with a static const POD member of a class template, right? We're still going through a get() function. If we constify the reference we should fix this problem too.
Agreed.
Aside: I'm not yet convinced that as a general principle, all instances of every immutable type ought to be declared const. This particular problem where we have a generalized conversion operator and a generalized assignment template looks like a corner case to me.
OK. I declare an object to be const when I want attempts to mutate the object to fail at compile time. IMO, it's nice to let users know when they're asking for something nonsensical (mutate an immutable object). OTOH, one could argue that letting people "mutate" an object with no state is harmless, and disallowing it could in fact hurt genericity. I haven't found that to be the case in practice, but I don't know. It's an interesting question. Also an interesting question is how to get the type system to enforce the immutability of a type. If there is a type which is inherently immutable (because it is empty, for instance), we have two options: - Const-qualify all the instances: Works, but is a hassle because you might miss a const somewhere. You could declare X_impl in a detail namespace, and make X a typedef for detail::X_impl const, but that only works if X is an actual type, not a template like keyword<>. (Template typedefs would fix this.) - Private copy-assign operator Would seem to be a better option, since it only involves a change in one location, but it would make the type non-POD (9/4), which is a deal-breaker for keyword<> since it should be statically initialized. Sorry, no answers here, just questions. :-P -- Eric Niebler Boost Consulting www.boost-consulting.com