reference to ‘_1’ is ambiguous

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

reference to ‘_1’ is ambiguous

sansanx
Hi,
 This problem has appeared before on the list but in a different
context.  The following code


 std::vector<int> myvec;
 for_each(myvec, std::cout<<_1<<' ');

 gives the error:

Serializer.h:78: error: reference to ‘_1’ is ambiguous
/home/sandeep/Computing/boost_1_38_0/boost/lambda/core.hpp:69: error:
candidates are: const boost::lambda::placeholder1_type&
boost::lambda::<unnamed>::_1
/home/sandeep/Computing/boost_1_38_0/boost/bind/placeholders.hpp:54:
error:                 boost::arg<1> <unnamed>::_1
Serializer.h:78: error: reference to ‘_1’ is ambiguous


I believe boost/bind is getting included indirectly via some other
library.  I have tried several modification but none seem to work as I
was quite reluctant to post a third mail on the list.

Thanks,
sandep
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Steven Watanabe-4
AMDG

Sandeep Gupta wrote:

>  This problem has appeared before on the list but in a different
> context.  The following code
>
>
>  std::vector<int> myvec;
>  for_each(myvec, std::cout<<_1<<' ');
>
>  gives the error:
>
> Serializer.h:78: error: reference to ‘_1’ is ambiguous
> /home/sandeep/Computing/boost_1_38_0/boost/lambda/core.hpp:69: error:
> candidates are: const boost::lambda::placeholder1_type&
> boost::lambda::<unnamed>::_1
> /home/sandeep/Computing/boost_1_38_0/boost/bind/placeholders.hpp:54:
> error:                 boost::arg<1> <unnamed>::_1
> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>
>
> I believe boost/bind is getting included indirectly via some other
> library.  I have tried several modification but none seem to work as I
> was quite reluctant to post a third mail on the list.
>  

qualify _1, either with boost::lambda:: or with some
namespace alias.

In Christ,
Steven Watanabe

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

sansanx
On Tue, Mar 17, 2009 at 8:50 PM, Steven Watanabe <[hidden email]> wrote:

> AMDG
>
> Sandeep Gupta wrote:
>>
>>  This problem has appeared before on the list but in a different
>> context.  The following code
>>
>>
>>  std::vector<int> myvec;
>>  for_each(myvec, std::cout<<_1<<' ');
>>
>>  gives the error:
>>
>> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>> /home/sandeep/Computing/boost_1_38_0/boost/lambda/core.hpp:69: error:
>> candidates are: const boost::lambda::placeholder1_type&
>> boost::lambda::<unnamed>::_1
>> /home/sandeep/Computing/boost_1_38_0/boost/bind/placeholders.hpp:54:
>> error:                 boost::arg<1> <unnamed>::_1
>> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>>
>>
>> I believe boost/bind is getting included indirectly via some other
>> library.  I have tried several modification but none seem to work as I
>> was quite reluctant to post a third mail on the list.
>>
>
> qualify _1, either with boost::lambda:: or with some
> namespace alias.
>

Thanks so much Steve. This was rather simple oversight. My mistake.

-Sandeep
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Johan Nilsson-4
In reply to this post by sansanx
Sandeep Gupta wrote:

> Hi,
>  This problem has appeared before on the list but in a different
> context.  The following code
>
>
>  std::vector<int> myvec;
>  for_each(myvec, std::cout<<_1<<' ');
>
>  gives the error:
>
> Serializer.h:78: error: reference to ‘_1’ is ambiguous
> /home/sandeep/Computing/boost_1_38_0/boost/lambda/core.hpp:69: error:
> candidates are: const boost::lambda::placeholder1_type&
> boost::lambda::<unnamed>::_1
> /home/sandeep/Computing/boost_1_38_0/boost/bind/placeholders.hpp:54:
> error:                 boost::arg<1> <unnamed>::_1
> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>
>
> I believe boost/bind is getting included indirectly via some other
> library.  I have tried several modification but none seem to work as I
> was quite reluctant to post a third mail on the list.

Disregaring the bind inclusion part, what about:

for_each(myvec, std::cout << ::boost::lambda::_1 << ' ');

/ Johan



_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Kenny Riddile
Johan Nilsson wrote:

> Sandeep Gupta wrote:
>> Hi,
>>  This problem has appeared before on the list but in a different
>> context.  The following code
>>
>>
>>  std::vector<int> myvec;
>>  for_each(myvec, std::cout<<_1<<' ');
>>
>>  gives the error:
>>
>> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>> /home/sandeep/Computing/boost_1_38_0/boost/lambda/core.hpp:69: error:
>> candidates are: const boost::lambda::placeholder1_type&
>> boost::lambda::<unnamed>::_1
>> /home/sandeep/Computing/boost_1_38_0/boost/bind/placeholders.hpp:54:
>> error:                 boost::arg<1> <unnamed>::_1
>> Serializer.h:78: error: reference to ‘_1’ is ambiguous
>>
>>
>> I believe boost/bind is getting included indirectly via some other
>> library.  I have tried several modification but none seem to work as I
>> was quite reluctant to post a third mail on the list.
>
> Disregaring the bind inclusion part, what about:
>
> for_each(myvec, std::cout << ::boost::lambda::_1 << ' ');
>
> / Johan

This has come up before for me, and I've always solved it in a similar way.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Noah Roberts
In reply to this post by sansanx
Sandeep Gupta wrote:
> On Tue, Mar 17, 2009 at 8:50 PM, Steven Watanabe <[hidden email]> wrote:
>> AMDG
>>
>> Sandeep Gupta wrote:

>>> Serializer.h:78: error: reference to ‘_1’ is ambiguous

>> qualify _1, either with boost::lambda:: or with some
>> namespace alias.
>>
>
> Thanks so much Steve. This was rather simple oversight. My mistake.
>

Would be nice if bind() didn't cause this.  Are the placeholders going
to be in an anonymous namespace when added to the std lib?

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Peter Dimov-5
Noah Roberts:
> Would be nice if bind() didn't cause this.

I can probably get the placeholders out of the global namespace in 1.41.

> Are the placeholders going to be in an anonymous namespace when added to
> the std lib?

No, they're in namespace std::placeholders.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Nat Goodspeed-2
Peter Dimov wrote:

> I can probably get the placeholders out of the global namespace in 1.41.

I saw a suggestion a while ago to share the *same* placeholders for
boost::bind, boost::lambda, Phoenix et al. I'm hoping that's where we're
headed?
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to ‘_1’ is ambiguous

Eric Niebler
In reply to this post by Peter Dimov-5
Peter Dimov wrote:
> Noah Roberts:
>> Would be nice if bind() didn't cause this.
>
> I can probably get the placeholders out of the global namespace in 1.41.
>
>> Are the placeholders going to be in an anonymous namespace when added
>> to the std lib?
>
> No, they're in namespace std::placeholders.

You, Joel de Guzman, Dan Marsden and I should coordinate. We might be
able to use Proto so that the bind placeholders can be shared with the
Phoenix placeholders, eliminating this source of confusion once and for all.

--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Peter Dimov-5
Eric Niebler:

> Peter Dimov wrote:
>> Noah Roberts:
>>> Would be nice if bind() didn't cause this.
>>
>> I can probably get the placeholders out of the global namespace in 1.41.
>>
>>> Are the placeholders going to be in an anonymous namespace when added to
>>> the std lib?
>>
>> No, they're in namespace std::placeholders.
>
> You, Joel de Guzman, Dan Marsden and I should coordinate. We might be able
> to use Proto so that the bind placeholders can be shared with the Phoenix
> placeholders, eliminating this source of confusion once and for all.

Bind can already use any placeholders (and in fact does recognize the Lambda
placeholders). No coordination is needed, just a specialization of
boost::is_placeholder.

The main problem is that all code that relies on the placeholders being
visible will break. A secondary problem I have is that to keep Bind
header-only I (think I) need to move to using inline functions instead of
objects for _K on all compilers. This will consume one release cycle, during
which the global placeholders will be "deprecated". The next release will
remove them from the global namespace.

But if there's a Boost-wide header that defines _K, I can easily make Bind
use it.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Peter Dimov-5
In reply to this post by Nat Goodspeed-2
Nat Goodspeed:
> Peter Dimov wrote:
>
>> I can probably get the placeholders out of the global namespace in 1.41.
>
> I saw a suggestion a while ago to share the *same* placeholders for
> boost::bind, boost::lambda, Phoenix et al. I'm hoping that's where we're
> headed?

Lambda only goes to _3 and it's not easy to remove this limit. I doubt that
anyone would invest the effort.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Eric Niebler
In reply to this post by Peter Dimov-5
Peter Dimov wrote:

> Eric Niebler:
>>
>> You, Joel de Guzman, Dan Marsden and I should coordinate. We might be
>> able to use Proto so that the bind placeholders can be shared with the
>> Phoenix placeholders, eliminating this source of confusion once and
>> for all.
>
> Bind can already use any placeholders (and in fact does recognize the
> Lambda placeholders). No coordination is needed, just a specialization
> of boost::is_placeholder.
>
> The main problem is that all code that relies on the placeholders being
> visible will break.

You mean code that requires the placeholders to be at global scope? Why
not bring them into the global scope with a using declaration?

> A secondary problem I have is that to keep Bind
> header-only I (think I) need to move to using inline functions instead
> of objects for _K on all compilers. This will consume one release cycle,
> during which the global placeholders will be "deprecated". The next
> release will remove them from the global namespace.

You are talking about ODR violations in code that refers to const
objects at namespace scope? There are ways around this problem....

namespace boost { namespace placeholders {

template<class I>
struct placeholder_instance
{
   placeholder<I> const value;
};

// statically initialized ...
template<class I>
placeholder<I> const placeholder_instance<I>::value = {{}};

namespace
{
   // This reference should also be statically initialized
   placeholder<mpl::int_<1> > const & _1 =
     placeholder_instance<mpl::int_<1> >::value;
}

}}

// for back-compatibility ...
using boost::placeholders::_1;

Now every use of _1 refers to the same object, even across translation
units, and it's all header-only. Not all compilers support this yet, but
Dave and I fought to get this approved for C++0x. For older compilers, I
think we can live with the ODR, as these objects will be stateless
(identity doesn't matter).

If placeholder<> is an appropriately-defined Proto terminal, then it can
be reused in Phoenix.

> But if there's a Boost-wide header that defines _K, I can easily make
> Bind use it.

I think it should all be possible.

--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Peter Dimov-5
Eric Niebler:
...
> namespace
> {
>   // This reference should also be statically initialized
>   placeholder<mpl::int_<1> > const & _1 =
>     placeholder_instance<mpl::int_<1> >::value;
> }

This is a problem for some precompiled header implementations. Some
compilers have fixed theirs to allow it, some have not, some only allow(ed?)
it when the variables are static.

Our tests don't show the problem since they don't use precompiled headers.
So we've relied on bug reports to iron these out, leading to the current
status quo in boost/bind/placeholders.hpp.

Using inline functions:

    static inline boost::arg<1> _1() { return boost::arg<1>(); }

is the most conservative option since it works everywhere, but it does have
the disadvantage that one cannot overload operators for _1.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Eric Niebler
Peter Dimov wrote:

> Eric Niebler:
> ...
>> namespace
>> {
>>   // This reference should also be statically initialized
>>   placeholder<mpl::int_<1> > const & _1 =
>>     placeholder_instance<mpl::int_<1> >::value;
>> }
>
> This is a problem for some precompiled header implementations.

Huh.

> Some
> compilers have fixed theirs to allow it, some have not, some only
> allow(ed?) it when the variables are static.

I notice I left "static" out of the example I sent around, but yes,
placeholder_instance<>::value is supposed to be a class static.

> Our tests don't show the problem since they don't use precompiled
> headers.

Step 1: add tests that exhibit the problem with precompiled headers.

> So we've relied on bug reports to iron these out, leading to
> the current status quo in boost/bind/placeholders.hpp.
>
> Using inline functions:
>
>    static inline boost::arg<1> _1() { return boost::arg<1>(); }
>
> is the most conservative option since it works everywhere, but it does
> have the disadvantage that one cannot overload operators for _1.

And bind is one of those libraries that we want to work even on ancient
compilers.... <sigh> Maybe we can have a separate Boost.Bind v2 library,
like we now have signals and signals2.

--
Eric Niebler
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: reference to '_1' is ambiguous

Peter Dimov-5
Eric Niebler:

> Peter Dimov wrote:
>> Eric Niebler:
>> ...
>>> namespace
>>> {
>>>   // This reference should also be statically initialized
>>>   placeholder<mpl::int_<1> > const & _1 =
>>>     placeholder_instance<mpl::int_<1> >::value;
>>> }
>>
>> This is a problem for some precompiled header implementations.
>
> Huh.

Yep. Apparently, the unnamed namespace does not get an unique name in every
translation unit because of the precompilation.

>> Some compilers have fixed theirs to allow it, some have not, some only
>> allow(ed?) it when the variables are static.
>
> I notice I left "static" out of the example I sent around, but yes,
> placeholder_instance<>::value is supposed to be a class static.

This is not what I meant. On some compilers (going by the #ifdefs, MSVC and
Metrowerks), this:

namespace
{
    X x;
}

doesn't work in a precompiled header, but this:

namespace
{
    static X x;
}

does (because a static x doesn't cause a multiple definition link error.)

On Borland, neither works in a PCH. On g++ 4, both work but the second
causes an "unused variable" warning for every _K that is not referenced,
which is a bit annoying. I'm not sure what works on g++ 3, but it uses the
inline function path. :-)

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users