template function instantiation

This is a discussion on template function instantiation within the C++ Programming forums, part of the General Programming Boards category; Hello everyone, For the following code from Bjarne's book, it is stated that template parameter T for function g will ...

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1,579

    template function instantiation

    Hello everyone,


    For the following code from Bjarne's book, it is stated that template parameter T for function g will be instantised as int other than double. My question is why there are not two instantiations for both int and double version of template function g?

    Code:
    // section C.13.8.3 Point of Instantiatant Binding
    
    template <class T> void f (T a) { g(a); }
    
    void g(int);
    
    void h()
    {
    	extern g (double);
    	f (2);
    }
    Here is the related statement from Bjarne,

    --------------------
    Each use of a template for a given set of template arguments defines a point of instantiation.
    That point is the nearest global or namespace scope enclosing its use,
    just before the declaration that contains that use.
    --------------------

    Does it before g (double) is not global function or namespace scope enclosing its use? If yes, I do not know why g (double) is not a global function, since it is declared as extern and some other compile unit should expose it?


    thanks in advance,
    George

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Uh, what? g isn't a template function, and the example as given is unambiguous. It's also not what's in my version of TC++PL. Are you sure you've reproduced it correctly?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi CornedBee,


    Are you challenging g(int) is not be able to instantise template function f to f(int)? Bjarne said it could...

    Refer to the book The C++ Programming Language, section C.13.8.3 Point of Instantiatant Binding.

    Any comments?

    Quote Originally Posted by CornedBee View Post
    Uh, what? g isn't a template function, and the example as given is unambiguous. It's also not what's in my version of TC++PL. Are you sure you've reproduced it correctly?

    regards,
    George

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    I have referred to it, but what you presented is an incorrect rendition of the example Bjarne gave. Perhaps your earlier edition had such an error, but I doubt it. Are you sure you've faithfully copied the example out?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    George2's example is exactly what I have in my copy of TC++PL (9th printing, January, 1999).

    Edit: 3rd edition
    Last edited by robatino; 03-06-2008 at 03:27 AM.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The example matches my 3rd Edition of TC++PL book - but it may be different in a more recent printing of the book.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,749
    Perhaps the code example is the same, but does the text say something to the effect of "template parameter T for function g will be instantised as int other than double"?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    OK, since the earlier prints are in error, I'll post what's in the 15th printing and explain the issue. Please note, however, that the example as given is still incorrect. (WTH was Stroustrup thinking when he wrote this?)

    C.13.8.3 says:
    Each use of a template for a given set of template arguments defines a point of instantiation. That point is in the nearest global or namespace scope enclosing its use, just before the declaration that contains that use. Fore example:
    Code:
    struct X { X(int); /* ... */ };
    
    void g(X);
    
    template <class T> void f(T a) { g(a); }
    
    void h()
    {
      extern void g(int);
      f(2); // Invokes f(X(2)); that is, f<X>(X(2)) -- Note: this comment is incorrect!
    }
    Here, the point of instantiation for f is just before h(), so the g() called in f() is the global g(X) rather than the local g(int).
    OK, so I pointed out that the comment is wrong. The line invokes f<int>(2), not f<X>(X(2)). However, that's not the point anyway.

    The point is that f<int>(2) in turn does not call g(int), which according to overloading rules is the best choice, but g(X) via the implicit conversion int->X. The reason is that the point of instantiation for f<int> is just before h(). So with the instantiation made explicit, the example looks like this:
    Code:
    struct X { X(int); /* ... */ };
    
    void g(X);
    
    template <class T> void f(T a) { g(a); }
    
    // This is the implicit instantiation of f<int>:
    void f(int a) { g(a); }
    void h()
    {
      extern void g(int);
      f(2); // Invokes f(X(2)); that is, f<X>(X(2)) -- Note: this comment is incorrect!
    }
    Note that the implementation of f<int> doesn't see the declaration of g(int). All it sees is the declaration of g(X). Therefore, g(int) is never considered, and g(X) is called.

    That's the entire issue.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi CornedBee,


    I have read your great reply. Still not sure 100&#37; grasp your points, since mixed reading of both your points and Bjarne's. Let me confirm three points before further discussion. Please let me know your points other than Bjarne's.

    1. function f is instantised to f<int> or f<X>?

    2. the invocation of f(2) inside main will invoke f<X> or f<int>?

    3. inside functon f, g(a) will call g(int) or g(X)?

    It is appreciated if you could provide your definite answer to the 3 small questions. :-)

    Quote Originally Posted by CornedBee View Post
    OK, since the earlier prints are in error, I'll post what's in the 15th printing and explain the issue. Please note, however, that the example as given is still incorrect. (WTH was Stroustrup thinking when he wrote this?)

    C.13.8.3 says:

    OK, so I pointed out that the comment is wrong. The line invokes f<int>(2), not f<X>(X(2)). However, that's not the point anyway.

    The point is that f<int>(2) in turn does not call g(int), which according to overloading rules is the best choice, but g(X) via the implicit conversion int->X. The reason is that the point of instantiation for f<int> is just before h(). So with the instantiation made explicit, the example looks like this:
    Code:
    struct X { X(int); /* ... */ };
    
    void g(X);
    
    template <class T> void f(T a) { g(a); }
    
    // This is the implicit instantiation of f<int>:
    void f(int a) { g(a); }
    void h()
    {
      extern void g(int);
      f(2); // Invokes f(X(2)); that is, f<X>(X(2)) -- Note: this comment is incorrect!
    }
    Note that the implementation of f<int> doesn't see the declaration of g(int). All it sees is the declaration of g(X). Therefore, g(int) is never considered, and g(X) is called.

    That's the entire issue.

    regards,
    George

  10. #10
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,622
    Quote Originally Posted by George2 View Post
    1. function f is instantised to f<int> or f<X>?
    f<int>

    2. the invocation of f(2) inside main will invoke f<X> or f<int>?
    f<int>

    3. inside functon f, g(a) will call g(int) or g(X)?
    g<X>
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    Why the following code block will instantise f to f<int> other than f<X>? You can see g's input parameter type is X.

    Code:
    struct X { X(int); /* ... */ };
    
    void g(X);
    
    template <class T> void f(T a) { g(a); }
    Quote Originally Posted by Elysia View Post
    f<int>


    f<int>


    g<X>

    regards,
    George

  12. #12
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,622
    Why would it instantiate to f<X> when f<int> is a better choice? You pass int, therefore it deduces the type to int. It's simple - the compiler tries a non-implicit cast solution first.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Or in other words, what does f's content have to do with its instantiation?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    May 2006
    Posts
    1,579
    Hi Elysia,


    1.

    Code:
    f(2);
    2.

    Code:
    void g(X);
    Quote Originally Posted by Elysia View Post
    Why would it instantiate to f<X> when f<int> is a better choice? You pass int, therefore it deduces the type to int. It's simple - the compiler tries a non-implicit cast solution first.
    (1) will instantise f to int and (2) will instantise f to X, and (2) is shown before (1).

    My question is,

    1. how do you think (1) will work and (2) will not work? How do you prove it?

    2. if you prove it, well, the rule will be more complex. The rule is not the nearest e.g. g(X) will instantise the temlpate function, right?


    Thanks CornedBee,


    Could you provide more information about what do you mean "f's content have to do with its instantiation" please? Do you mean the definition or declaration of g will not trigger instantiation of function f or something else? More information please?

    Quote Originally Posted by CornedBee View Post
    Or in other words, what does f's content have to do with its instantiation?

    regards,
    George

  15. #15
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,622
    Quote Originally Posted by George2 View Post
    (1) will instantise f to int and (2) will instantise f to X, and (2) is shown before (1).

    My question is,

    1. how do you think (1) will work and (2) will not work? How do you prove it?

    2. if you prove it, well, the rule will be more complex. The rule is not the nearest e.g. g(X) will instantise the temlpate function, right?

    Thanks CornedBee,

    Could you provide more information about what do you mean "f's content have to do with its instantiation" please? Do you mean the definition or declaration of g will not trigger instantiation of function f or something else? More information please?
    If you listen, you'll know that the compiler will not deduce a template type depending on the contents of the function itself. So whatever you may rename g to, and whatever type it may take, whether or not the compiler can send a type to it with or without implicit conversions, it will still deduce the type of T depending on the arguments you pass to the function.

    In this case, the compiler can pass int directly instead of performing an implicit conversion to X. Therefore it will always instantiate f<int>.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Deducing Function Template Arguments
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 03-12-2008, 07:29 PM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 01:53 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 12:03 PM
  4. C++ compilation issues
    By Rupan in forum C++ Programming
    Replies: 1
    Last Post: 08-22-2005, 05:45 AM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 11:54 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21