Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2006-09-27 15:47:18


"Eric Niebler" <eric_at_[hidden]> 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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk