[Q] Template function - linking problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dmitry Epstein

    [Q] Template function - linking problem

    Here is an example of a problem, which I tried to reduce to its
    bare essentials:

    // begin test1.cpp
    class E {
    public:
    template<class T> static void f();
    };

    template<class T> void E::f() {}

    class C {};

    int main()
    {
    E::f<C>();
    return 0;
    }
    // end test1.cpp


    This compiles and links fine. Now I split the same code into three
    different files:

    // begin e.h
    class E {
    public:
    template<class T> static void f();
    };
    // end e.h

    // begin e.cpp
    #include "e.h"

    template<class T> void E::f() {}
    // end e.cpp

    // begin test2.cpp
    #include "e.h"

    class C {};

    int main()
    {
    E::f<C>();
    return 0;
    }
    // end test2.cpp


    This compiles fine, but when I try to link (in Visual Studio 2003),
    I get this error:

    test error LNK2019: unresolved external symbol "public: static void
    __cdecl E::f<class C>(void)" (??$f@VC@@@E@@S AXXZ) referenced in
    function _main

    What is wrong here?

    --
    Dmitry Epstein
    Northwestern University, Evanston, IL. USA
    mitia(at)northw estern(dot)edu
  • Leor Zolman

    #2
    Re: [Q] Template function - linking problem

    On 04 Apr 2004 00:48:47 GMT, Dmitry Epstein
    <mitia.nospam@n orthwestern.edu .invalid> wrote:
    [color=blue]
    >alfps@start. no (Alf P. Steinbach) wrote in
    >news:406f5750. 158635171@news. individual.net:[color=green]
    >> * Dmitry Epstein <mitia.nospam@n orthwestern.edu .invalid>
    >> schriebt:[color=darkred]
    >>> // begin e.h
    >>> class E {
    >>> public:
    >>> template<class T> static void f();
    >>> };
    >>> // end e.h
    >>>
    >>> What is wrong here?[/color]
    >>
    >> The compiler cannot instantiate the template without having
    >> access to the full template definition, which you should
    >> simply put in the header file.[/color]
    >
    >Hm, I know that I can compile a template function all by itself,
    >and some sort of code is generated at that point. How does the
    >compiler deal with the absence of a concrete instantiation, and why
    >does it become a problem elsewhere, like in my example?[/color]

    If a compiler just sees a function /template/ in a TU, with no implicit or
    explicit specializations of it, then no code is generated whatsoever. If
    there /are/ specializations , only the code for those is generated. (In a
    class template, in fact, only member functions actually used somehow
    [called, or have their addresses taken] get instantiated, unless you use
    explicit instantiation.)
    [color=blue]
    >[color=green]
    >> Another possibility is to avoid instantiation at the point of
    >> usage by instantiating the template somewhere else for the
    >> relevant types.
    >>
    >> But that restricts usage of the template to those types.[/color]
    >
    >This doesn't sound like what I want to do, but how would I
    >instantiate the template "somewhere else"? Can you give an
    >example?[/color]

    For a class template C defined beginning with:

    template<typena me T>
    class C {
    ...
    };

    explicit instantiation would be accomplished with:

    template<>
    class C<int>;


    You can do the same for function templates, or selected member functions of
    a class template.
    -leor
    [color=blue]
    >
    >Thanks.[/color]

    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: Download BD Software's free STL Error Message Decryptor at:
    An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

    Comment

    • Alf P. Steinbach

      #3
      Re: [Q] Template function - linking problem

      * Dmitry Epstein <mitia.nospam@n orthwestern.edu .invalid> schriebt:[color=blue]
      > // begin e.h
      > class E {
      > public:
      > template<class T> static void f();
      > };
      > // end e.h
      >
      > What is wrong here?[/color]

      The compiler cannot instantiate the template without having access to
      the full template definition, which you should simply put in the header
      file.

      Another possibility is to avoid instantiation at the point of usage by
      instantiating the template somewhere else for the relevant types.

      But that restricts usage of the template to those types.

      --
      A: Because it messes up the order in which people normally read text.
      Q: Why is top-posting such a bad thing?
      A: Top-posting.
      Q: What is the most annoying thing on usenet and in e-mail?

      Comment

      • Dmitry Epstein

        #4
        Re: [Q] Template function - linking problem

        alfps@start.no (Alf P. Steinbach) wrote in
        news:406f5750.1 58635171@news.i ndividual.net:[color=blue]
        > * Dmitry Epstein <mitia.nospam@n orthwestern.edu .invalid>
        > schriebt:[color=green]
        >> // begin e.h
        >> class E {
        >> public:
        >> template<class T> static void f();
        >> };
        >> // end e.h
        >>
        >> What is wrong here?[/color]
        >
        > The compiler cannot instantiate the template without having
        > access to the full template definition, which you should
        > simply put in the header file.[/color]

        Hm, I know that I can compile a template function all by itself,
        and some sort of code is generated at that point. How does the
        compiler deal with the absence of a concrete instantiation, and why
        does it become a problem elsewhere, like in my example?
        [color=blue]
        > Another possibility is to avoid instantiation at the point of
        > usage by instantiating the template somewhere else for the
        > relevant types.
        >
        > But that restricts usage of the template to those types.[/color]

        This doesn't sound like what I want to do, but how would I
        instantiate the template "somewhere else"? Can you give an
        example?

        Thanks.

        --
        Dmitry Epstein
        Northwestern University, Evanston, IL. USA
        mitia(at)northw estern(dot)edu

        Comment

        • Leor Zolman

          #5
          Re: [Q] Template function - linking problem

          On 04 Apr 2004 00:48:47 GMT, Dmitry Epstein
          <mitia.nospam@n orthwestern.edu .invalid> wrote:
          [color=blue]
          >alfps@start. no (Alf P. Steinbach) wrote in
          >news:406f5750. 158635171@news. individual.net:[color=green]
          >> * Dmitry Epstein <mitia.nospam@n orthwestern.edu .invalid>
          >> schriebt:[color=darkred]
          >>> // begin e.h
          >>> class E {
          >>> public:
          >>> template<class T> static void f();
          >>> };
          >>> // end e.h
          >>>
          >>> What is wrong here?[/color]
          >>
          >> The compiler cannot instantiate the template without having
          >> access to the full template definition, which you should
          >> simply put in the header file.[/color]
          >
          >Hm, I know that I can compile a template function all by itself,
          >and some sort of code is generated at that point. How does the
          >compiler deal with the absence of a concrete instantiation, and why
          >does it become a problem elsewhere, like in my example?[/color]

          If a compiler just sees a function /template/ in a TU, with no implicit or
          explicit specializations of it, then no code is generated whatsoever. If
          there /are/ specializations , only the code for those is generated. (In a
          class template, in fact, only member functions actually used somehow
          [called, or have their addresses taken] get instantiated, unless you use
          explicit instantiation.)
          [color=blue]
          >[color=green]
          >> Another possibility is to avoid instantiation at the point of
          >> usage by instantiating the template somewhere else for the
          >> relevant types.
          >>
          >> But that restricts usage of the template to those types.[/color]
          >
          >This doesn't sound like what I want to do, but how would I
          >instantiate the template "somewhere else"? Can you give an
          >example?[/color]

          For a class template C defined beginning with:

          template<typena me T>
          class C {
          ...
          };

          explicit instantiation would be accomplished with:

          template<>
          class C<int>;


          You can do the same for function templates, or selected member functions of
          a class template.
          -leor
          [color=blue]
          >
          >Thanks.[/color]

          --
          Leor Zolman --- BD Software --- www.bdsoft.com
          On-Site Training in C/C++, Java, Perl and Unix
          C++ users: Download BD Software's free STL Error Message Decryptor at:
          An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

          Comment

          Working...