From: Brendan on
I have some code like:

std::for_each(pairVecVec.begin(),
pairVecVec.end(),
printNVPairs);

Where printNVPairs has a couple of overloads. So printNVPairs needs
to be disambiguated. There seem to be a few ways to do this.

1. Write a wrapper function with a different name
2. Assign printNVPairs to a temporary variable that has the proper
type.
3. Cast printNVPairs

My first question is whether 3 is a *safe* way to disambiguate. Could:
(void (*)(NVPairVector&)) printNVPairs

potentially take the wrong overload, and simply cast it to the other
type? Obviously that could cause undefined behaviour when I eventually
calls a function with the wrong arguments.

What about:
static_cast<void (*)(NVPairVector&)>(printNVPairs)

is that any safer according to the standard?

Are there any other cleaner ways to disambiguate an overloaded
function when passing to a template function?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: cpp4ever on
On 06/29/2010 02:27 AM, Brendan wrote:
> I have some code like:
>
> std::for_each(pairVecVec.begin(),
> pairVecVec.end(),
> printNVPairs);
>
> Where printNVPairs has a couple of overloads. So printNVPairs needs
> to be disambiguated. There seem to be a few ways to do this.
>
> 1. Write a wrapper function with a different name
> 2. Assign printNVPairs to a temporary variable that has the proper
> type.
> 3. Cast printNVPairs
>
> My first question is whether 3 is a *safe* way to disambiguate. Could:
> (void (*)(NVPairVector&)) printNVPairs
>
> potentially take the wrong overload, and simply cast it to the other
> type? Obviously that could cause undefined behaviour when I eventually
> calls a function with the wrong arguments.
>
> What about:
> static_cast<void (*)(NVPairVector&)>(printNVPairs)
>
> is that any safer according to the standard?
>
> Are there any other cleaner ways to disambiguate an overloaded
> function when passing to a template function?
>

These types of problem frequently require the use of fully qualified
names to ensure the intended function or variable is used. Another
solution is to create a function which requires the parameter types you
wish to parse. I certainly don't like the static_cast solution. Perhaps
a more complete example would help here.

cpp4ever

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Yechezkel Mett on
On Jun 29, 4:27 am, Brendan <catph...(a)catphive.net> wrote:
> I have some code like:
>
> std::for_each(pairVecVec.begin(),
> pairVecVec.end(),
> printNVPairs);
>
> Where printNVPairs has a couple of overloads. So printNVPairs needs
> to be disambiguated. There seem to be a few ways to do this.
>
> 1. Write a wrapper function with a different name
> 2. Assign printNVPairs to a temporary variable that has the proper
> type.
> 3. Cast printNVPairs
>

You might want to use something like implicit_cast<> which can be
defined as follows:

template<class T>
T implicit_cast(T source) { return source; }

which gives you the safety of option 2 but with a syntax similar to
option 3.

Yechezkel Mett


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 29 Jun., 03:27, Brendan <catph...(a)catphive.net> wrote:
> I have some code like:
>
> std::for_each(pairVecVec.begin(),
> pairVecVec.end(),
> printNVPairs);
>
> Where printNVPairs has a couple of overloads. So printNVPairs needs
> to be disambiguated. There seem to be a few ways to do this.
>
> 1. Write a wrapper function with a different name
> 2. Assign printNVPairs to a temporary variable that has the proper
> type.
> 3. Cast printNVPairs
>
> My first question is whether 3 is a *safe* way to disambiguate. Could:
> (void (*)(NVPairVector&)) printNVPairs
>
> potentially take the wrong overload, and simply cast it to the other
> type? Obviously that could cause undefined behaviour when I eventually
> calls a function with the wrong arguments.
>
> What about:
> static_cast<void (*)(NVPairVector&)>(printNVPairs)
>
> is that any safer according to the standard?
>
> Are there any other cleaner ways to disambiguate an overloaded
> function when passing to a template function?

I remember having attacked this problem once by providing
a function template that takes advantage of systematic
usage of non-deduced contexts, e.g.:

namespace N {

template<class Iter>
void for_each(Iter begin, Iter end, void (*f)(
const typename std::iterator_traits<Iter>::value_type&))
{
std::for_each(begin, end, f);
}

}

The disadvantage is, that you cannot even deduce the
function return type.

A somewhat nicer solution is possible with lambda
expressions in C++0x:

std::for_each(pairVecVec.begin(), pairVecVec.end(),
[](decltype(*pairVecVec.begin()) x) { printNVPairs(x); });

HTH & Greetings from Bremen,

Daniel Kr�gler



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Hakusa on
On Jun 28, 9:27 pm, Brendan <catph...(a)catphive.net> wrote:

> My first question is whether 3 is a *safe* way to disambiguate. Could:
> (void (*)(NVPairVector&)) printNVPairs
>
> potentially take the wrong overload, and simply cast it to the other
> type? Obviously that could cause undefined behaviour when I eventually
> calls a function with the wrong arguments.
>
> What about:
> static_cast<void (*)(NVPairVector&)>(printNVPairs)
>
> is that any safer according to the standard?
>
> Are there any other cleaner ways to disambiguate an overloaded
> function when passing to a template function?

Using typedefs for each overload would be a start.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]