Boost logo

Boost Users :

Subject: Re: [Boost-users] thread/call_once compile error on trunk on my code
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-04-21 18:00:50


Le 21/04/13 19:46, Olaf Peter a écrit :
> Hi,
>>
>> the error
>> /usr/local/include/boost/thread/detail/invoke.hpp:406:65: error: invalid
>> initialization of non-const reference of type '{anonymous}::id_string&'
>> from an rvalue of type '{anonymous}::id_string'
>>
>> says you that the parameter (const) can not be used where a non-const is
>> expected.
>>
>> Shouldn't the operator be declared non-const
>>
>> std::string const& operator()(id::type id) ;
>
> The idea was to create a lazy lookup since this functor is only used
> on debugging, but compiled/linked at all build targets (I know,
> project structure ...). Imo making the member const/non-const is a
> taste of matter; const since it does primary a lookup, non-const due
> to the lazy initialization. So, I'm not sure.
I don't think the compiler lets you choose. If do_init expect a non
const, you must pass a non-const.
>
>> In addition if you want to pass a reference you would need to use
>> boost::ref().
>>
>> The following compile well without the patch
>>
>> struct id_string
>> {
>> static boost::once_flag flag;
>> static void do_init(id_string & )
>> {}
>> void operator()()
>> {
>> boost::call_once(flag, &id_string::do_init, boost::ref(*this));
>> }
>> };
> >
>> Note that the following compiles
>>
>> struct id_string
>> {
>> static boost::once_flag flag;
>> static void do_init(id_string & )
>> {}
>> void operator()()
>> {
>> std::bind(&id_string::do_init, std::ref(*this))();
>> }
>> void operator()(int) const
>> {
>> std::bind(&id_string::do_init, *this)();
>> }
>> };
>>
>> I would expect that the preceding fails as *this is a 'id_string const&'
>> and do_init expects an 'id_string &'.
>> This would explain why with the patch it worked as the patch was calling
>> to std::bind.
>>
> you mean using boost::ref? I'm not sure if I have std::ref on my old
> gcc compiler 4.6.3. Anyway, with thread/detail/invoke.hpp from
> Revision: 83985
>
>
> std::string const& operator()(id::type id)
> {
> boost::call_once(flag, &id_string::do_init,
> boost::ref(*this));
>
> map_iterator s = m_map.find(id);
>
> if (s == m_map.end()) {
> return m_map[id::invalid];
> } else {
> return s->second;
> }
> ...
> }
>
> compiles,
Great.
> but not std::string const& operator()(id::type id) const, neither with
> ref or cref.
>
As I said it is normal that compilation fails in this case. *this is
'id_string const&' and do init expects 'id_string &'

Best,
Vicente


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net