Topic: Explicit function template instantiation


Author: emberson@fx.com (Richard M. Emberson)
Date: 1995/04/14
Raw View
Q: Can an explicit function template instantiation be
    within a method?


For example this works (compiles using g++):


#include <string>
#include "some stl headers"

class Foo {
    typedef set<Foo*> Set;
public:
    const string& name() const;
    Foo* find(Foo* foo);
....
    Set set_;
};

class Finder {
public:
    Finder(Foo* foo) : foo_(foo) {}
    bool operator()(Foo* foo) {
        return (foo.name() == foo_.name());
    }
    Foo* foo_;
};

template Foo::Set::iterator find_if(
    Foo::Set::iterator,
    Foo::Set::iterator,
    Finder
);

Foo* Foo::find(Foo* foo) {
    Finder finder(foo);
    Set::iterator i = find_if(set_.begin(), set_.end(), finder);
    return (i != set_.end()) ? (*i) : 0;
}



And this does NOT work:

#include <string>
#include "some stl headers"

class Foo {
    typedef set<Foo*> Set;
public:
    const string& name() const;
    Foo* find(Foo* foo);
....
    Set set_;
};

Foo* Foo::find(Foo* foo) {
    class Finder {
    public:
        Finder(Foo* foo) : foo_(foo) {}
        bool operator()(Foo* foo) {
            return (foo.name() == foo_.name());
        }
        Foo* foo_;
    };

    template Foo::Set::iterator find_if(
        Foo::Set::iterator,
        Foo::Set::iterator,
        Finder
    );
    Finder finder(foo);
    Set::iterator i = find_if(set_.begin(), set_.end(), finder);
    return (i != set_.end()) ? (*i) : 0;
}





My question is why not. Is g++ (2.6.3 plus) wrong. The ANSI/ISO
Resolutions A document, section r.14.9 Explicit instantiations,
does not state where such instantiation statements can appear.

If no other method will use the class Finder and therefore the
particular instantiation of find_if that uses Finder, should not
the explicit instantiation be able to be declared within the
method.

Richard Emberson

--

Dow Jones Telerate Systems, Inc.    mail: emberson@fx.com
2465 Faber Place                    uucp: uunet!fx!emberson
Palo Alto, California 94303         phone: 415/858-7777-242





Author: rjl@f111.iassf.easams.com.au (Rohan LENARD)
Date: 1995/04/16
Raw View
In article <1995Apr14.165146.18649@fx.com>,
Richard M. Emberson <emberson@fx.com> wrote:
>Q: Can an explicit function template instantiation be
>    within a method?
>

No.

  14.3.2                  DRAFT: 1 February 1995        Templates  14-17
  Point of instantiation


14An explicit specialization or explicit  instantiation  of  a  template  |
  shall  be  in  the  namespace  in which the template was defined.  For
  example:

          namespace N {
                  template<class T> class X { /* ... */ };
                  template<class T> class Y { /* ... */ };
                  template<class T> class Z {
                          void f(int i) { g(i); }
                          // ...
                  };

                  class X<int> { /* ... */ }; // ok: specialization
                                              //     in same namespace
          }


          template class Y<int>; // error: explicit instantiation
                                 //        in different namespace


          template class N::Y<char*>; // ok: explicit instantiation
                                      //     in same namespace


          class N::Y<double> { /* ... */ }; // ok: specialization         |
                                            //     in same namespace      |


Regards,
 Rohan

--
----------------------------------------------------------------------------
rjl@iassf.easams.com.au | All quotes can be attributed to my automated quote
Rohan Lenard            | writing tool.  Yours for just $19.95; and if you
+61-2-367-4555          | call now you'll get a free set of steak knives ...





Author: jason@cygnus.com (Jason Merrill)
Date: Fri, 20 Jan 1995 18:38:14 GMT
Raw View
>>>>> Richard M Emberson <emberson@fx.com> writes:

> Q: Can an explicit function template instantiation be
>  within a method?

Well, according to the grammar in the September WP, explicit instantiations
cannot appear anywhere, because the 'explicit-instantiation' nonterminal
does not appear in any productions.

My personal opinion is that it should be an expansion of 'declaration', in
which case the answer to your question would be "no".

> If no other method will use the class Finder and therefore the
> particular instantiation of find_if that uses Finder, should not
> the explicit instantiation be able to be declared within the
> method.

The template may be unused elsewhere, but that does not mean that you can
define the template itself within the method.  Explicit instantiation does
not introduce any names into any scope, so there is no reason to allow it
to nest.

Jason




Author: emberson@fx.com (Richard M. Emberson)
Date: Thu, 19 Jan 1995 16:29:52 GMT
Raw View
Q: Can an explicit function template instantiation be
 within a method?


For example this works (compiles using g++):


#include <string>
#include "some stl headers"

class Foo {
 typedef set<Foo*> Set;
public:
 const string& name() const;
 Foo* find(Foo* foo);
....
 Set set_;
};

class Finder {
public:
    Finder(Foo* foo) : foo_(foo) {}
    bool operator()(Foo* foo) {
        return (foo.name() == foo_.name());
    }
    Foo* foo_;
};

template Foo::Set::iterator find_if(
 Foo::Set::iterator,
 Foo::Set::iterator,
 Finder
);

Foo* Foo::find(Foo* foo) {
 Finder finder(foo);
 Set::iterator i = find_if(set_.begin(), set_.end(), finder);
 return (i != set_.end()) ? (*i) : 0;
}







And this does NOT work:

#include <string>
#include "some stl headers"

class Foo {
    typedef set<Foo*> Set;
public:
    const string& name() const;
 Foo* find(Foo* foo);
....
    Set set_;
};

Foo* Foo::find(Foo* foo) {
 class Finder {
 public:
     Finder(Foo* foo) : foo_(foo) {}
     bool operator()(Foo* foo) {
         return (foo.name() == foo_.name());
     }
     Foo* foo_;
 };

 template Foo::Set::iterator find_if(
     Foo::Set::iterator,
     Foo::Set::iterator,
     Finder
 );
    Finder finder(foo);
    Set::iterator i = find_if(set_.begin(), set_.end(), finder);
    return (i != set_.end()) ? (*i) : 0;
}




My question is why not. Is g++ (2.6.3 plus) wrong. The ANSI/ISO
Resolutions A document, section r.14.9 Explicit instantiations,
does not state where such instantiation statements can appear.

If no other method will use the class Finder and therefore the
particular instantiation of find_if that uses Finder, should not
the explicit instantiation be able to be declared within the
method.

Richard Emberson
--

Dow Jones Telerate Systems, Inc.    mail: emberson@fx.com
2465 Faber Place                    uucp: uunet!fx!emberson
Palo Alto, California 94303         phone: 415/858-7777-242