template instantiation and typedefs.

Discussion in 'C++' started by aiooua@gmail.com, Dec 8, 2006.

  1. Guest

    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,
    --
    ajd.
    , Dec 8, 2006
    #1
    1. Advertising

  2. Micah Cowan Guest

    wrote:
    > 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?


    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).
    Micah Cowan, Dec 8, 2006
    #2
    1. Advertising

  3. Douglas Dude Guest

    wrote:
    > 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,
    > --
    > ajd.


    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 ?
    Douglas Dude, Dec 8, 2006
    #3
  4. wrote:
    > 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.
    Gianni Mariani, Dec 8, 2006
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fernando Cuenca
    Replies:
    4
    Views:
    2,515
    Gianni Mariani
    Sep 6, 2004
  2. Thomas Maier-Komor
    Replies:
    6
    Views:
    605
    Thomas Maier-Komor
    May 19, 2005
  3. Replies:
    1
    Views:
    562
    Salt_Peter
    Dec 25, 2006
  4. Ed
    Replies:
    1
    Views:
    340
  5. Noah Roberts
    Replies:
    6
    Views:
    1,133
    Johannes Schaub (litb)
    Feb 2, 2011
Loading...

Share This Page