Thread: MSDN template sample

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

    MSDN template sample

    Hello everyone,


    For the MSDN template sample,

    http://msdn2.microsoft.com/en-us/library/w98s4hs8.aspx

    My questions are,

    1. does void
    Code:
    f(char) { printf_s("f(char)\n");}
    or
    Code:
    g('c');
    instantise function g to parameter type char?

    2. "This can cause overloads to be declared after the template (but before the template is instantiated) to be seen." What does this mean?


    thanks in advance,
    George

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1) The second one. Do you see a "g" anywhere within f's body?

    2) It's the point of the article. Go back to the Stroustrup thread, read my long explanation, and think about what overloads are visible in the 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

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


    I found after discussion with you these days, most of my confusions are solved. Cool!!

    But still one confusion can not be solved, I show my confusion in below code.

    I do not know why there is compile error below (compile error posted), and if I remove statement "cout << d.get_i() << endl; // output 200", there will not be any compile errors?

    My confusion is, I think whether or not we call get_i, Derived<int> is instantised, right? Instantised means having the same code, why whether we call a member function or not will impact compile result? Is there some new rules we do not cover theses days about instantiation of template class?

    Compile errors,

    1>------ Build started: Project: test_template4, Configuration: Debug Win32 ------
    1>Compiling...
    1>main.cpp
    1>d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(15) : error C2955: 'Base' : use of class template requires template argument list
    1> d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(5) : see declaration of 'Base'
    1> d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(21) : see reference to class template instantiation 'Derived<T>' being compiled
    1>d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(15) : error C2955: 'Base' : use of class template requires template argument list
    1> d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(5) : see declaration of 'Base'
    1> d:\visual studio 2008\projects\test_template4\test_template4\main.c pp(26) : see reference to class template instantiation 'Derived<T>' being compiled
    1> with
    1> [
    1> T=int
    1> ]

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <typename T> struct Base {
    public:	
    	Base (int _i): i (_i)
    	{
    
    	}
    
    	int i;
    };
    
    template <typename T> struct Derived : public Base/*<T>*/ {
    public:
    	Derived (int _i) : Base<T> (_i)
    	{
    	}
    	int get_i() { return i; }
    };
    
    
    int main()
    {
    	Derived<int> d (200);
    	cout << d.get_i() << endl; // output 200
    	return 0;
    }
    Quote Originally Posted by CornedBee View Post
    1) The second one. Do you see a "g" anywhere within f's body?

    2) It's the point of the article. Go back to the Stroustrup thread, read my long explanation, and think about what overloads are visible in the instantiation.

    regards,
    George

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Members of templates get instantiated separately from their class definition. If you use Derived<int>, the definition of Derived<int> gets instantiated. By declaring an object of type Derived<int> you instantiate the definition (it's your first use) and the constructor. But only when you call get_i do you actually instantiate it, which is why the error can hide until then.

    But only on some compilers! Note that, since i in get_it is non-dependent, the compiler is allowed to bind it immediately and will fail to do so. GCC is one such compiler.
    Code:
    earlybind.cpp: In member function ‘int Derived<T>::get_i()’:
    earlybind.cpp:20: error: ‘i’ was not declared in this scope
    That's after I remove the comments around Base's template parameters. That's invalid, too, you know.
    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,


    1.

    Quote Originally Posted by CornedBee View Post
    Members of templates get instantiated separately from their class definition.
    Does C++ Spec mentions this? Or it is implementation defined behavior? Like MSVC has this behavior?

    How about normal class (non-template)? If there are errors (e.g. undefined names) in some member function and there are compile errors only when we call these member functions?

    2.

    Quote Originally Posted by CornedBee View Post
    But only on some compilers! Note that, since i in get_it is non-dependent, the compiler is allowed to bind it immediately and will fail to do so. GCC is one such compiler.
    Code:
    earlybind.cpp: In member function ‘int Derived<T>::get_i()’:
    earlybind.cpp:20: error: ‘i’ was not declared in this scope
    Do you mean you removed get_i call in main, and still get this error in GCC? Sorry I did not catch your points exactly.

    3.

    Quote Originally Posted by CornedBee View Post
    That's after I remove the comments around Base's template parameters. That's invalid, too, you know.
    Not sure what are you doing. I have checked in my original code, there is no comments around Base's template parameters. What is the code you referred to? Could you show your complete code please? :-)


    regards,
    George

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1) The spec says so, yes.
    Normal classes are never instantiated, they just are. All binding is done immediately and therefore all these rules don't apply.

    2) Yep. I comment out the call and get the same error.

    3)
    template <typename T> struct Derived : public Base/*<T>*/ {
    These comments.
    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!


    Two more comments,

    1.

    Quote Originally Posted by CornedBee View Post
    2) Yep. I comment out the call and get the same error.
    Do you mean the following code compile error in your side? I can compile fine. I am using Visual Studio 2008. In the following code, only class is instantised, no member functions are called.

    Code:
    #include <iostream>
    
    using namespace std;
    
    template <typename T> struct Base {
    public:	
    	Base (int _i): i (_i)
    	{
    
    	}
    
    	int i;
    };
    
    template <typename T> struct Derived : public Base <T> {
    public:
    	Derived (int _i) : Base<T> (_i)
    	{
    	}
    	int get_i() { return i; }
    };
    
    
    int main()
    {
    	Derived<int> d (200);
    	// cout << d.get_i() << endl; // output 200
    	return 0;
    }
    2.

    Quote Originally Posted by CornedBee View Post
    3)
    These comments.
    Do you mean you can not compile if we make base class non-template? I am confused. It could compile in my envionrment. Are you using the code below?

    Code:
    #include <iostream>
    
    using namespace std;
    
    /*template <typename T> */ struct Base {
    public:	
    	Base (int _i): i (_i)
    	{
    
    	}
    
    	int i;
    };
    
    template <typename T> struct Derived : public Base/* <T>*/ {
    public:
    	Derived (int _i) : Base/*<T>*/ (_i)
    	{
    	}
    	int get_i() { return i; }
    };
    
    
    int main()
    {
    	Derived<int> d (200);
    	cout << d.get_i() << endl; // output 200
    	return 0;
    }

    regards,
    George

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    1) Yes, we have established that you can compile fine. GCC can't. The C++ standard calls it a "quality of implementation issue" - in this case, GCC is of higher quality, because it immediately reports the error you've made, instead of waiting until you actually use the function.

    2) Is it so hard to find the line I gave you in the code? In the base clause of Derived, you commented out the template parameters for Base. That's invalid, and only accepted by VC++ because of an MS compiler extension. This is the code I use:
    Code:
    #include <iostream>
    
    using namespace std;
    
    template <typename T> struct Base {
    public:
            Base (int _i): i (_i)
            {
    
            }
    
            int i;
    };
    
    template <typename T> struct Derived : public Base<T> {
    public:
            Derived (int _i) : Base<T> (_i)
            {
            }
            int get_i() { return i; }
    };
    
    
    int main()
    {
            Derived<int> d (200);
    //      cout << d.get_i() << endl; // output 200
            return 0;
    }
    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.

    You mean in my original code, there will be compile error when we instantise the Derived template class even if we do not use its get_i member function in GCC? So, error comes from this line?

    Code:
    Derived<int> d (200);
    Quote Originally Posted by CornedBee View Post
    1) Yes, we have established that you can compile fine. GCC can't. The C++ standard calls it a "quality of implementation issue" - in this case, GCC is of higher quality, because it immediately reports the error you've made, instead of waiting until you actually use the function.
    2.

    Quote Originally Posted by CornedBee View Post
    2) Is it so hard to find the line I gave you in the code? In the base clause of Derived, you commented out the template parameters for Base. That's invalid, and only accepted by VC++ because of an MS compiler extension. This is the code I use:
    Why my code is invalid? Do you mean when a derived class is a template class, base class has to be a template class?

    Here is my code? Where do you mean invalid?

    Code:
    #include <iostream>
    
    using namespace std;
    
    /*template <typename T> */ struct Base {
    public:	
    	Base (int _i): i (_i)
    	{
    
    	}
    
    	int i;
    };
    
    template <typename T> struct Derived : public Base/* <T>*/ {
    public:
    	Derived (int _i) : Base/*<T>*/ (_i)
    	{
    	}
    	int get_i() { return i; }
    };
    
    
    int main()
    {
    	Derived<int> d (200);
    	cout << d.get_i() << endl; // output 200
    	return 0;
    }

    regards,
    George

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    2) http://cboard.cprogramming.com/showp...19&postcount=3
    The code you posted there looked different. Base was a template, but you didn't supply parameters.

    Of course the base of a template doesn't have to be a template. Note, however, that if it isn't, the special rules no longer apply and no compile error is created by your unqualified access of i.

    1) No, the error is there whether you instantiate Derived or not. That's because the unqualified name is bound in the first stage, when parsing the template, not when instantiating it.
    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,


    Code:
    Derived<int> d (200);
    Quote Originally Posted by CornedBee View Post
    1) No, the error is there whether you instantiate Derived or not. That's because the unqualified name is bound in the first stage, when parsing the template, not when instantiating it.
    Do you mean the compile error from the compiler is not from above line? If not, which line comes the compile error in your compiler?

    This line?

    Code:
    int get_i() { return i; }

    regards,
    George

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Code:
    int get_i() { return i; }
    This line.
    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,


    Quote Originally Posted by CornedBee View Post
    Code:
    int get_i() { return i; }
    This line.
    Question answered.


    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. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  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