6

Beware: This is GCC 4.1.2. We're on a proprietary embedded platform. We cannot update to a new compiler. So C++03 + TR1 it is.

We somewhere have a function like this:

template<typename T>
void foo(const boost::any& x)
{
  bar(boost::any_cast<T>(x));
}

which is then later used in a bind expression:

std::tr1::bind( &foo<T>, _1);

This generates the following error:

error: call of overloaded 'ref(const boost::any&)' is ambiguous
note: candidates are: std::tr1::reference_wrapper<_Tp> std::tr1::ref(_Tp&) [with _Tp = const boost::any]
note: const boost::reference_wrapper boost::ref(T&) [with T = const boost::any]

I do understand that this is Koenig lookup hitting us. However, I lack ideas about how to circumvent this problem.

Anyone out there?

sbi
  • 219,715
  • 46
  • 258
  • 445
  • 1
    Is the lack of `ref` in your code intentional? – Simple Dec 12 '13 at 15:04
  • 1
    @Simple: Where do you see a lacking `ref`? – sbi Dec 12 '13 at 15:10
  • Your two code samples don't have a call to `ref`, whereas the error does. I was asking whether that is intentional or not. By your mention of ADL I wasn't sure. – Simple Dec 12 '13 at 15:20
  • @Simple: It's deep down in the implementation of `std::tr1::bind` that an unqualified call to `ref()` is made with a `boost::any` as a parameter. Koenig lookup seems to make `boost::ref()` just as good a match as `std::tr1::ref()` for this call. Hence the error. Anyway, Dietmar's nice idea employing a special overload solved this. – sbi Dec 12 '13 at 15:24
  • @sbi: it seems odd that the implementation seems to use an unqualified `ref()`. If it uses `ref()` it should really qualify it. – Dietmar Kühl Dec 12 '13 at 15:24
  • @Dietmar: Yes, it does call it unqualifiedly. Note that we're stuck with GCC4.1, though, which is quite old. I suppose this is fixed in newer versions. – sbi Dec 13 '13 at 07:11

1 Answers1

5

Define a version of boost::ref() specifically taking a boost::any and have it return the proper type. Probably

namespace boost {
    std::tr1::reference_wrapper<boost::any const>
    ref(boost::any const& o) {
        return std::tr1::ref(o);
    }
}
Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380