Thread: template definition

  1. #1
    Registered User
    Join Date
    May 2009
    Posts
    242

    template definition

    I have some questions about the way in which Prata (C++ Primer Plus, pp. 756ff.) defines an array template which is supposed to show how you would use a template argument for array size (hence the int n). My questions have to do with the use of "explicit" and "virtual" in the prototypes. Here's the relevant part of the code:

    Code:
    template <class T, int n>
    class ArrayTP
    {
    private:
    	T ar[n];
    public:
    	ArrayTP() {};
    	explicit ArrayTP(const T & v);
    	virtual T & operator[](int i);
    	virtual T operator[](int i) const;
    };
    
    template <class T, int n>
    ArrayTP<T, n>::ArrayTP(const T & v)
    {
    	for (int i = 0; i < n; i++)
    		ar[i] = v;
    }
    
    template <class T, int n>
    T & ArrayTP<T, n>::operator[](int i)
    {
    	if (i < 0 || i >=n)
    	{
    		std::cerr << "Error in array limits: " << i
    			<< " is out of range\n";
    		std::exit(EXIT_FAILURE);
    	}
    	return ar[i];
    }
    First, as to the "explicit": This is to prevent unintended type conversions, right? But here, it would be converting a type to a type array, wouldn't it? Like, if T is double, then the explicit just prevents a double from being unintentionally converted into an array of doubles if you happen to make a mistake in naming your variables.

    So, first question on that: Am I understanding the reasoning behind it correctly? If I am, this seems fairly paranoid even by my standards (and I tend to be pretty paranoid). Or is it just a good habit to write "explicit" on anything that could be an unwanted type conversion without giving a lot of thought to whether it's realistic or not (which, admittedly, is nearly impossible to anticipate in all cases).

    Second, on the use of "virtual" for the indexing operators (the const version is the same as the one in the above code): That seems to be an invitation to modify this definition in any derived class. But, aside from the error messages, which are certainly up for grabs, I don't see any reason why one would ever want to change this implementation.

    Or does he do this just as an indicator that this class is intended as a potential base class?

  2. #2
    Registered User
    Join Date
    May 2009
    Posts
    242
    One more question, this one regarding the overloading of operator[]. Is it important that the version that returns the value of a T object be the last one shown in the prototype in order to hide the version that returns a reference unless a reference is required?

    This overloading seems kind of strange, since both versions have the same signature--except that the second version can't be called by a constant array.

  3. #3
    Registered User
    Join Date
    May 2009
    Posts
    242
    I think I just figured out how the operator[] overloading is working. Running a few tests, it looks to me like the reference version (first prototype) is always used unless the calling object is a constant.

    I'll have to see whether changing the order influences anything.

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Aisthesis View Post
    First, as to the "explicit": This is to prevent unintended type conversions, right? But here, it would be converting a type to a type array, wouldn't it? Like, if T is double, then the explicit just prevents a double from being unintentionally converted into an array of doubles if you happen to make a mistake in naming your variables.
    It is to prevent nonsensical implicit conversions. It often happens that the compiler can instantiate a temporary object using the constructor and use it in some statement.
    For example, say you had a class where comparisons to ints are nonsensical (but you could of course compare your class to another of the same class), yet you have a constructor that takes an int or a similar type. The constructor would instantiate a temporary object of your class with the int and then compare them.
    To prevent these kinds of things, you would declare the constructor as explicit.

    So, first question on that: Am I understanding the reasoning behind it correctly? If I am, this seems fairly paranoid even by my standards (and I tend to be pretty paranoid). Or is it just a good habit to write "explicit" on anything that could be an unwanted type conversion without giving a lot of thought to whether it's realistic or not (which, admittedly, is nearly impossible to anticipate in all cases).
    This is usually "good programming practice" to prevent mistakes. You might need it for other reasons too, which could be detected through testing, but since it is usually considered good programming practice, I do not know if I would dwell on the why here so much.

    Second, on the use of "virtual" for the indexing operators (the const version is the same as the one in the above code): That seems to be an invitation to modify this definition in any derived class. But, aside from the error messages, which are certainly up for grabs, I don't see any reason why one would ever want to change this implementation.

    Or does he do this just as an indicator that this class is intended as a potential base class?
    I would say it is the later. I do not see why they would need to be virtual otherwise.
    However, you never know for what reason someone may want to change your class. Perhaps to remove the bounds checking?

    Quote Originally Posted by Aisthesis View Post
    One more question, this one regarding the overloading of operator[]. Is it important that the version that returns the value of a T object be the last one shown in the prototype in order to hide the version that returns a reference unless a reference is required?

    This overloading seems kind of strange, since both versions have the same signature--except that the second version can't be called by a constant array.
    Quote Originally Posted by Aisthesis View Post
    I think I just figured out how the operator[] overloading is working. Running a few tests, it looks to me like the reference version (first prototype) is always used unless the calling object is a constant.

    I'll have to see whether changing the order influences anything.
    The idea here is to allow access to elements in the array which can be modified and also a version when operating on a const object. Say that you pass a const reference to the array; then you cannot call the original operator [] since it is declared as non-const. However, if it was declared const, then it could not return a non-const reference since that would break the promise. So they have overloaded another const version, which is also usually standard practice.
    Although I would like to see it return const T& instead of T, but the principle still applies.
    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.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    242
    tx, Elysia, that pretty much answers my questions completely.

    As an off-topic aside, I notice you say that your blurb lists MS Windows 7 and Visual Studio 2008. I've installed the latter on my XP machine with no problems but can't get it (and several other programs) to install on my Vista laptop, which somehow won't let me put the files in Program Files (x86). If I want to do a complete wipe of the laptop (format c before installing Windows 7, which is my plan as soon as I have a little cash, is there any way to use the upgrade? Or should I just bite the bullet and pay the extra $80 for the full version?

    From the hype, I'm gathering 7 preserves some of the protection but also improves one's ability to modify the settings. Anyhow, it's kind of aggravating just having visual studio express on the laptop when I have the full version sitting here ready to go...

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    > is there any way to use the upgrade?

    http://www.winsupersite.com/win7/upgrade_01.asp
    (In case my guess is wrong, there are more articles. Find the one that fits your situation.)

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Sure you can upgrade. You can easily get around the whole you can only upgrade to your current version of Windows problem, like upgrading from Vista Ultimate to Win 7 Home Premium.
    Also be sure to run the installers as admin or disable UAC to enable the possibility of installing to your programs folder.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  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. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 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