Boost logo

Boost Users :

Subject: [Boost-users] Making boost::any play nice in function overloads
From: dakatz_at_[hidden]
Date: 2010-09-28 13:09:10


Hi -

I've got a method which should take a variety of types and with the
exception of taking a function pointer it shouldn't care about which
types it's getting, so I thought that a boost::any would be a nice way
to achieve this. Here's a simplified prototype:

------------------------------------------------------------------------
class Table
{
public:
    // Base case
    void doSomething(const boost::any& input);

    // Special overload for function pointers for some special reason.
    //
    // Has logic to interpret NULL pointer as integer 0 and pass to
    // "base" boost::any case.
    void doSomething(void (*f)(void));
};
------------------------------------------------------------------------

When I tried to call doSomething with a string literal argument
(i.e. table.doSomething("Hello")), it of course failed since boost:any
can't be initialized with an array. Okay - no problem. Another
overload should do the trick, right?

So I added an overload like this:

------------------------------------------------------------------------
class Table
{
public:
    void doSomething(const boost::any& input);

    // Supposed to take a const char*, convert it to a string, and
    // pass off to boost::any case.
    void doSomething(const std::string& input);

    void doSomething(void (*f)(void));
};
------------------------------------------------------------------------

on the theory that a const char* would convert to a std::string. I
couldn't add an overload for const char* directly since that would
conflict with the overload for the function pointer
(i.e. table.doSomething(0) would be ambiguous between the function
pointer and the const char*). Unfortunately, this didn't work. When I
called this with "Hello.":

------------------------------------------------------------------------
$ g++ -W -Wall -Werror -ansi any_overload_problem.cpp
any_overload_problem.cpp: In function 'int main()':
any_overload_problem.cpp:32: error: call of overloaded 'doSomething(const char [7])' is ambiguous
any_overload_problem.cpp:8: note: candidates are: void Table::doSomething(const boost::any&)
any_overload_problem.cpp:19: note: void Table::doSomething(const std::string&)
------------------------------------------------------------------------

I admit that I didn't foresee this, although I suppose I should have.
Even though a boost:any can't be initialized with a const char*, that
signature is still participating in the overload resolution.

So does anyone have any suggestions for how to deal with this sort of
thing? Is there a good way to get the boost::any conversions to match
"less well" than something like the std::string conversion? Or am I
just way off-base in trying to use boost::any here at all?

Thanks!

Dan Katz


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