template instantiation and typedefs.

A

aiooua

Any idea why the following code does not compile?

----
#include<iostream>
#include<list>
using namespace std;

class Base {
public:
int val;
Base(int i):val(i){}
void show(){cout<<name()<<val<<endl;}
virtual string name() = 0;
};
class A: public Base{
public:
A(int i):Base(i){}
string name() { return "a";}
};

class B: public Base{
public:
B(int i):Base(i){}
string name() { return "b";}
};

typedef list<A*>::iterator a_iter;
typedef list<B*>::iterator b_iter;
typedef pair<a_iter,a_iter> a_seq;
typedef pair<b_iter,b_iter> b_seq;

template <class T> Base* show(pair<typename list<T*>::iterator,
typename list<T*>::iterator> seq, int val){
for(typename list<T*>::iterator i = seq.first; i!=seq.second; ++i)
if(i->val==val) i->show();
}

int main(){
list<A*> a_list;
list<B*> b_list;
for(int i=0;i<10;i++){
a_list.push_back(new A(i));
b_list.push_back(new B(i));
}
a_seq a = make_pair(a_list.begin(),a_list.end());
b_seq b = make_pair(b_list.begin(),b_list.end());
show(a, 5);
show(b, 6);
}
---

I get the following compilation errors.
---
test.cpp: In function `int main()':
test.cpp:43: no matching function for call to `show(a_seq&, int)'
test.cpp:44: no matching function for call to `show(b_seq&, int)'
--

both a_seq and b_seq are typedefed to pairs of list iterator. am i
missing something?

thanks,
 
M

Micah Cowan

Any idea why the following code does not compile?

----
#include<iostream>
#include<list>
using namespace std;

class Base {
public:
int val;
Base(int i):val(i){}
void show(){cout<<name()<<val<<endl;}
virtual string name() = 0;
};
class A: public Base{
public:
A(int i):Base(i){}
string name() { return "a";}
};

class B: public Base{
public:
B(int i):Base(i){}
string name() { return "b";}
};

typedef list<A*>::iterator a_iter;
typedef list<B*>::iterator b_iter;
typedef pair<a_iter,a_iter> a_seq;
typedef pair<b_iter,b_iter> b_seq;

template <class T> Base* show(pair<typename list<T*>::iterator,
typename list<T*>::iterator> seq, int val){
for(typename list<T*>::iterator i = seq.first; i!=seq.second; ++i)
if(i->val==val) i->show();
}

int main(){
list<A*> a_list;
list<B*> b_list;
for(int i=0;i<10;i++){
a_list.push_back(new A(i));
b_list.push_back(new B(i));
}
a_seq a = make_pair(a_list.begin(),a_list.end());
b_seq b = make_pair(b_list.begin(),b_list.end());
show(a, 5);
show(b, 6);
}

If you try it without the convenient typedefs, you'll find it still
doesn't work.

The standard refers to two contexts in which template argument
deduction is impossible for function templates. One of these is the
situation you're encountering: inside the qualification part of a
qualified identifier (that is, you can't deduce T from A<T>::B).

The other case is when you try to deduce a template argument from
another template id that uses the template parameter-to-be-deduced
within an expression; say:

template<int i> struct B {
static const int value = i;
};

template<int i> void bfunc(B<i-2> &b) {}

int main(void)
{
B<10> b;
bfunc(b);
}

The implementation can't deduce that it should call bfunc<12>(b).
 
D

Douglas Dude

Any idea why the following code does not compile?

----
#include<iostream>
#include<list>
using namespace std;

class Base {
public:
int val;
Base(int i):val(i){}
void show(){cout<<name()<<val<<endl;}
virtual string name() = 0;
};
class A: public Base{
public:
A(int i):Base(i){}
string name() { return "a";}
};

class B: public Base{
public:
B(int i):Base(i){}
string name() { return "b";}
};

typedef list<A*>::iterator a_iter;
typedef list<B*>::iterator b_iter;
typedef pair<a_iter,a_iter> a_seq;
typedef pair<b_iter,b_iter> b_seq;

template <class T> Base* show(pair<typename list<T*>::iterator,
typename list<T*>::iterator> seq, int val){
for(typename list<T*>::iterator i = seq.first; i!=seq.second; ++i)
if(i->val==val) i->show();
}

int main(){
list<A*> a_list;
list<B*> b_list;
for(int i=0;i<10;i++){
a_list.push_back(new A(i));
b_list.push_back(new B(i));
}
a_seq a = make_pair(a_list.begin(),a_list.end());
b_seq b = make_pair(b_list.begin(),b_list.end());
show(a, 5);
show(b, 6);
}
---

I get the following compilation errors.
---
test.cpp: In function `int main()':
test.cpp:43: no matching function for call to `show(a_seq&, int)'
test.cpp:44: no matching function for call to `show(b_seq&, int)'
--

both a_seq and b_seq are typedefed to pairs of list iterator. am i
missing something?

thanks,

show(pair,val) with no template type is in use together with an
irrelevent return to the base which should be empty.
I guess pointers used might also sicken your program, mightnot they ?
 
G

Gianni Mariani

Any idea why the following code does not compile? ....
template <class T> Base* show(pair<typename list<T*>::iterator,
typename list<T*>::iterator> seq, int val){

The compiler can't deduce a dependant type.

....
both a_seq and b_seq are typedefed to pairs of list iterator. am i
missing something?


Think about it for a second. The compiler would need to check every
possible specialization of that template class (which is infinite) to
deduce.

One methodology I use is:

template <typename T> Base * show( const T & a, int b, check<T> c = 0 );

check<T> is a compile time assertion for the right type of T when
instantiated.

When deducing template function arguments, if the compiler envounters an
error instatitaing a parameter type, that specialization is excluded.
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top