Thread: name binding from one template to another

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

    name binding from one template to another

    Hello everyone,


    For non-template function/class, compiler knows the symbol is there and bind to a definite symbol. It is straight forward to understand.

    But for a two-step name-lookup compiler, I am curious, how did compiler binds another referred template from one template in the first name lookup step, before instantiation?

    Since template symbol is not finalized until it is instantised. But during the first step of compiler look-up, the compiler only sees the definition of template, how could it bind (generate binary code to link to some symbol) (before a referred template is instantised, the real code is not generated)?

    For example, in the following code, during the 1st step of name-lookup before function func is instantised, how did compiler work internally to bind to vector<T> (T is not ready at this time, so vector<T> is not instantised)?

    Or, I am wrong that compiler will do nothing to bind the referred template, like vector<T> in the sample?

    Code:
    template <class T> void func (T a)
    {
        vector<T> vc;
        vc.push_back (a);
        // ...
    }

    thanks in advance,
    George

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It can bind vector<T> to the std::vector template easily. That doesn't mean it generates code for it yet.
    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
    Thanks CornedBee,


    Actually, my confusion comes from the sample we discussed before after re-thinking. In the below sample, Bjarne mentioned before v is not a dependent name since vector is defined in file vector.

    So, it means during the 1st phase of name lookup when compiler parsing the definition of the template function sum, compiler should make v refers to something?

    If we instantise T to int, compiler should bind v to vector<int> type and when we instantise T to double, compiler should bind v to vector<double> type.

    But actually since T is not given at the time during template definition, vector<T> is not instantised. How could v refers to something in the 1st phase of compile?

    Code:
    #include <vector>
    bool tracing;
    / / ...
    template <class T> T sum (std :: vector <T>& v)
    {
    T t = 0 ;
    if (tracing) cerr << "s u m (" << &v << ")\ n ";
    for (int i = 0 ; i <v .size(); i ++) t = t + v [i ];
    return t ;
    }
    Quote Originally Posted by CornedBee View Post
    It can bind vector<T> to the std::vector template easily. That doesn't mean it generates code for it yet.

    regards,
    George

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Why shouldn't the compiler be able to let v refer to vector<T> "for now"? You're creating an issue where there is none.
    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
    May 2006
    Posts
    1,579
    Thanks CornedBee,


    My confusion is, a compiler should do two major working items,

    1. Identify the type of variable;
    2. Identify referred symbols (find declaration), like function call.

    If either task can not be completed when paring a section of code (e.g. a
    function), it should be dependent name on template parameter and could only
    be resolved when instantiation is done.

    In my understanding, each type has an identifier and compiler needs to match
    variable with related type identifier (like typeid typeof operator, giving
    variable a type tag). For the sample, how could compiler identify what type
    of v is? So, I think v is dependent on template parameter.

    I do not understand why it is treated as a template parameter non-dependent
    name in your minds and also in Bjarne's points.

    Code:
    #include <vector>
    bool tracing;
    / / ...
    template <class T> T sum (std :: vector <T>& v)
    {
    T t = 0 ;
    if (tracing) cerr << "s u m (" << &v << ")\ n ";
    for (int i = 0 ; i <v .size(); i ++) t = t + v [i ];
    return t ;
    }

    regards,
    George

    Quote Originally Posted by CornedBee View Post
    Why shouldn't the compiler be able to let v refer to vector<T> "for now"? You're creating an issue where there is none.

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The meaning of vector<T> cannot change, no matter what T is. You cannot overload class templates on their template parameters. You can specialize them, which is similar, but the selection mechanism for specializations is such that the meaning of vector<T> still doesn't change.
    Therefore, template arguments do not make a class template name dependent.

    As for the compiler stuff, don't make assumptions about how compilers work.
    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

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


    For class argument in your statement below, in statement vector<T>& v, you mean v or T?

    Quote Originally Posted by CornedBee View Post
    Therefore, template arguments do not make a class template name dependent.

    regards,
    George

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I do not have the phrase "class argument" in my statement.
    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
    Thanks CornedBee,


    1.

    Quote Originally Posted by CornedBee View Post
    I do not have the phrase "class argument" in my statement.
    I mean type argument. Any comments to my post #7?

    2.

    For example,

    Code:
    template <class T> void func (T a)
    {
        vector<T> vc;
        T tmp = a;
        vc.push_back (a);
    
        return;
    }
    In the above code, a, tmp are dependent names and vc is not dependent name.

    My understanding correct?


    regards,
    George

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No. The only dependent name in this sample is push_back, and that's an extremely simple case.
    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

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


    What is your rule to decide what is a dependent name or not?

    If compiler judge from the point that if the type is unknown until instantiation time, then it belongs to dependent name, then a, tmp and along with push_back are both dependent names. So, what makes me confused is compiler's metrics about what is dependent name and what is not. Any ideas or comments?

    Code:
    template <class T> void func (T a)
    {
    vector<T> vc;
    T tmp = a;
    vc.push_back (a);
    
    return;
    }
    Quote Originally Posted by CornedBee View Post
    No. The only dependent name in this sample is push_back, and that's an extremely simple case.

    regards,
    George

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    What is your rule to decide what is a dependent name or not?
    Dependent names are
    1) Names of free functions if one of the arguments' types depends on a template parameter somehow. (Is a template parameter, is a member of a type that depends on a template parameter, or is parametrized with a type that depends on a template parameter.)
    These dependent names trigger two-stage lookup.

    2) Names of members of types that depend on a template parameter. (See the definition above.) This is the case for push_back above.
    These dependent names trigger the explicit disambiguation rule, i.e. you have to tell the compiler if it's a type (prefix with typename), a template (prefix with template), or a data or function member (don't prefix).
    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

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


    1.

    I am confused about " is a member of a type that depends on a template parameter" and " is parametrized with a type that depends on a template parameter"? Could you show pseudo code for them separately?

    2.

    Do you mean non-dependent names could all be resolved in the 1st phase of two phase name look-up? If yes, in my sample in post #11, a and tmp are non-depdnent names, but since they are of type T, they still could not be resolved in definition phase. Any comments?

    Quote Originally Posted by CornedBee View Post
    Dependent names are
    1) Names of free functions if one of the arguments' types depends on a template parameter somehow. (Is a template parameter, is a member of a type that depends on a template parameter, or is parametrized with a type that depends on a template parameter.)
    These dependent names trigger two-stage lookup.

    2) Names of members of types that depend on a template parameter. (See the definition above.) This is the case for push_back above.
    These dependent names trigger the explicit disambiguation rule, i.e. you have to tell the compiler if it's a type (prefix with typename), a template (prefix with template), or a data or function member (don't prefix).

    regards,
    George

  14. #14
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1)
    A template parameter: T
    A member of a template parameter: T::iterator (needs typename for disambiguation)
    A member of a member of a template parameter: T::iterator::difference_type (needs typename for disambiguation)
    A type parametrized by a template parameter: vector<T>
    A member of a type parametrized by a template parameter: vector<T>::iterator (needs typename for disambiguation)
    A member of a type parametrized by a member of a type parametrized by a template parameter: iterator_traits<vector<T>::iterator>::category (needs typename twice for disambiguation: first in the parameter for iterator_traits, and then again for the whole expression, so the complete, valid expression is: typename iterator_traits<typename vector<T>::iterator>::category)

    ... and so on.

    2) You misunderstand what "resolve" means. It merely means that the compiler knows which entity a name refers to. The names tmp and a are trivially resolved: one is a parameter of the current function, the other a local variable. That their exact type isn't yet known is irrelevant.
    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

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


    1.

    I want to check that dependent name and non-dependent name have nothing to do with whether names are bound at definition phase or instantiation phase of two phased name lookup.

    For example, you mentioned a and tmp are not dependent names, but I think they can not be resolved until instantiation time, since you do not know T until instantiation.

    2.

    What is the purpose of categoring names into dependent name and non-dependent name, if some non-dependent names still can not be bound during definition phase and have to be bound during instantiation time, like variable a and tmp in my sample?

    Quote Originally Posted by CornedBee View Post
    1)
    A template parameter: T
    A member of a template parameter: T::iterator (needs typename for disambiguation)
    A member of a member of a template parameter: T::iterator::difference_type (needs typename for disambiguation)
    A type parametrized by a template parameter: vector<T>
    A member of a type parametrized by a template parameter: vector<T>::iterator (needs typename for disambiguation)
    A member of a type parametrized by a member of a type parametrized by a template parameter: iterator_traits<vector<T>::iterator>::category (needs typename twice for disambiguation: first in the parameter for iterator_traits, and then again for the whole expression, so the complete, valid expression is: typename iterator_traits<typename vector<T>::iterator>::category)

    ... and so on.

    2) You misunderstand what "resolve" means. It merely means that the compiler knows which entity a name refers to. The names tmp and a are trivially resolved: one is a parameter of the current function, the other a local variable. That their exact type isn't yet known is irrelevant.

    regards,
    George

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Specialising a member function with a template template parameter
    By the4thamigo_uk in forum C++ Programming
    Replies: 10
    Last Post: 10-12-2007, 04:37 AM
  2. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  3. error: template with C linkage
    By michaels-r in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2006, 08:11 AM
  4. late binding with template function
    By clf in forum C++ Programming
    Replies: 1
    Last Post: 03-28-2002, 01:13 PM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM