partial specialization - why is this NOT ambiguous?

S

sks_cpp

template< class a, class b, class c = int >
struct something
{
};

template< class a, class b >
struct something<a, b>
{
};


Why is the following line NOT ambiguous (according to gcc)?

something<int, bool> a;

Shouldn't that be ambiguous?
 
G

Gianni Mariani

sks_cpp wrote:
....
Shouldn't that be ambiguous?

#include <iostream>

template< class a, class b, class c = int >
struct something
{
something() { std::cout << "A\n"; }
};

template< class a, class b >
struct something<a, b>
{
something() { std::cout << "B\n"; }
};


something<int, bool, int> a;
something<int, bool> b;

int main()
{
}

.... why does this print

B
B

?

BTW - next time post compilable code.

I would guess this is an error in GCC but I still don't grok all the
fine points of templates so I may be wrong.
 
J

John Harrison

sks_cpp said:
template< class a, class b, class c = int >
struct something
{
};

template< class a, class b >
struct something<a, b>
{
};


Why is the following line NOT ambiguous (according to gcc)?

something<int, bool> a;

Shouldn't that be ambiguous?

I don't think so. The second template looks more specialised than the first
to me.

Ambiguity is not the issue. The compiler picks the most specialised
template, the second is more specialised because (for instance)
something<int, int, int> will match the first not the second, but there is
no substitutions that will match the second and not the first. Therefore the
second is more specialised.

john
 
G

Gianni Mariani

John said:
I don't think so. The second template looks more specialised than the first
to me.

Ambiguity is not the issue. The compiler picks the most specialised
template, the second is more specialised because (for instance)
something<int, int, int> will match the first not the second, but there is
no substitutions that will match the second and not the first. Therefore the
second is more specialised.

so what *should* this print.

#include <iostream>

template< class a, class b, class c = int >
struct something
{
something() { std::cout << "A\n"; }
};

template< class a, class b >
struct something<a, b>
{
something() { std::cout << "B\n"; }
};


something<int, bool, int> a;
something<int, bool> b;

int main()
{
}
 
J

John Harrison

Forget my first post, I was getting confused between your case and the
choice between alternate partial template specialisations. Since you only
have one partial template specialisation, it will be used if it is matched.

Your example is clever because it confuses two different processes. My take
on it is this. By saying

template< class a, class b, class c = int > something ...

in the primary template you are saying that whenever the template something
appears with two arguments a third int argument is added. I.e.

something<int, int> a; is equivalent to something <int, int, int> a;

and also that

template< class a, class b >
struct something<a, b>
{
};

is equivalent to

template< class a, class b >
struct something<a, b, int>
{
};

Once we see that, it obvious whether the specialisation applies or not. If
the third template argument is an int (explicitly or implicitly), use the
specialisation. I.e.

something<int, int> a; // implicit int, use specialisation
something<int, int, int> b; // explicit int, use specialisation
something<int, int, double> c; // not an int, use primary

john
 
R

Rob Williscroft

Gianni Mariani wrote in

#include <iostream>
#include <ostream>
#include <iomanip>

template< class a, class b, class c = int >
struct something
{
};

template< class a, class b >
struct something<a, b>
{
};


something<int, bool> a;


int main()
{
using namespace std;

cout << "It compiled" << endl;
}

Try it and see, I get:

It compiled

With 3 different compilers.

Rob.
 
T

tom_usenet

template< class a, class b, class c = int >
struct something
{
};

template< class a, class b >
struct something<a, b>
{
};


Why is the following line NOT ambiguous (according to gcc)?

something<int, bool> a;

Shouldn't that be ambiguous?

No, you have the partial specialization:

template <class a, class b>
struct something<a, b, int>

which obviously matches something<int, bool, int>. Default parameters
are syntatic sugar, they don't effect things like specialization.

Tom
 

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
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top