function template overloading and typedef in GCC

A

Arkadiy Vertleyb

Hi all,

I am having a problem trying to overload a function template, based on
a typedef, such as:

template<class T>
struct A
{};

template<class T>
struct B
{
typedef A<T> type;
};

template<class T>
void foo(const typename B<T>::type&)
{}

void bar()
{
foo(B<int>::type());
}

g++ 3.3.1 complains at the above code with the following message:
no matching function for call to `foo(A<int>)'

Similar code works with no problem in VC6.

Am I missing something?

Thanks in advance,

Arkadiy
 
G

Gianni Mariani

Arkadiy said:
Hi all,

I am having a problem trying to overload a function template, based on
a typedef, such as:

template<class T>
struct A
{};

template<class T>
struct B
{
typedef A<T> type;
};

template<class T>
void foo(const typename B<T>::type&)
{}

void bar()
{
foo(B<int>::type());
}

g++ 3.3.1 complains at the above code with the following message:
no matching function for call to `foo(A<int>)'

Similar code works with no problem in VC6.

Am I missing something?

Even if this is not allowed by the standard (which I think it is given
some things I've seen - just a hunch) the error message is totally wrong.

Besides:

foo<int>(B<int>::type());

compiles fine.

I suggest you post a bug on gcc. Before you do, you might want to try a
gcc 3.4 devel snapshot. Some template things (like this) have been
fixed in the development branch.
 
T

tom_usenet

Hi all,

I am having a problem trying to overload a function template, based on
a typedef, such as:

template<class T>
struct A
{};

template<class T>
struct B
{
typedef A<T> type;
};

template<class T>
void foo(const typename B<T>::type&)

The above contains a non-deducable context (in this case, a nested
type). This means that calls to the function cannot rely on template
argument deduction, but must use explicit template argument
specification.

The reason this is non-deducable is that the mapping from nested type
to containing type is not in general one-to-one. Often many different
Ts would give the same B said:
{}

void bar()
{
foo(B<int>::type());


g++ 3.3.1 complains at the above code with the following message:
no matching function for call to `foo(A<int>)'
Right.

Similar code works with no problem in VC6.

Yes, this is a bizarre "feature" of VC6 that it deduces this kind of
non-deducable context.
Am I missing something?

Just that VC6 is very old and non-standard.

Tom
 
G

Gianni Mariani

tom_usenet said:
The above contains a non-deducable context (in this case, a nested
type).


What's non-deductible about it ?

const typename B<T>::type& <<>> B<int>::type

infers T is int. right ?

How does the standard define non-deductible ?

I must admit, I've never come across this kind of problem, so I really
don't know. Time to brush up ...
 
T

tom_usenet

What's non-deductible about it ?

It attempts to deduce a template parameter from the type of a typedef
of the template. 14.8.2.4/4 is the relevent bit of the standard.
const typename B<T>::type& <<>> B<int>::type

infers T is int. right ?

No, and the deduction can't even reliably be made. e.g.

template<>
struct B<float>
{
typedef A<int> type; //whoops, now which B?
};

Of course, this could just cause an ambiguity error, as it does in
VC6. However, the mapping from inner type to template parameter is not
always many-to-one, so the committee decided to forbid it.
How does the standard define non-deductible ?

Read up on nondeduced contexts.

Tom
 
A

Arkadiy Vertleyb

Hi guys,

Thanks for your responce.

Come to think about it, I do realize that overloading on a nested
typedef in this context (at least in my case) doesn't make a lot of
sense. The nested typedef may after all resolve to different types,
like:

template<class T>
struct A1
{};

template<class T>
struct A2
{};

template<class T>
struct B
{
// something like:
typedef select<some_condition_based_on_T, A1<T>, A2<T> >::type type;
};

For both A1 and A2 I need to define a separate overloaded function.
So I actually have to overload on A1<T> and A2<T>, rather than on
B<T>::type.

Regards,

Arkadiy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,143
Messages
2,570,822
Members
47,368
Latest member
michaelsmithh

Latest Threads

Top