
"Eric Niebler" <eric@boost-consulting.com> writes:
The BOOST_PARAMETER_KEYWORD(tag, name) macro expands, in part, to something like:
keyword<tag::name> & name = ...;
Shouldn't this be:
keyword<tag::name> const & name = ...; ^^^^^
What is the reason for using a non-const ref here?
There didn't seem to be any reason to make it const.
These things are not mutable.
If immutability is a property of the type, it wouldn't seem to be important to additionally label the object as const.
In fact, it is causing me problems. Consider a placeholder type with an implicit conversion operator:
struct default_constructed_t { template<typename T> operator T() const { return T(); } };
default_constructed_t const default_constructed = {};
BOOST_PARAMETER_KEYWORD(tag, value)
Now, when I do this: "value = default_constructed;" I get this error:
main.cpp:306: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: /cygdrive/c/boost/consulting/svn/main/boost/1.33.1/backports/boost_1_33_1/boost/parameter/ keyword.hpp:59: note: candidate 1: const typename boost::parameter::aux::tag<Tag, const T>::type boost::parameter::keyword<T>::operator=(const T&) const [with T = default_constructed_t, Tag = tag::value] /cygdrive/c/boost/consulting/svn/main/boost/1.33.1/backports/boost_1_33_1/boost/parameter/ keyword.hpp:32: note: candidate 2: boost::parameter::keyword<tag::value>& boost::parameter::keyword<tag::value>::operator=(const boost::parameter::keyword<tag::value>&)
Had the keyword object been const, the call would not have been ambiguous.
True enough. I suppose we have no interest in enabling that second overload (the implicitly generated assignment operator) for any purpose, so it makes sense to make the keywords references-to-const. 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. 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. -- Dave Abrahams Boost Consulting www.boost-consulting.com