Page 1 of 1

C++ templates (error for Class own reference)...

Posted: Thu May 19, 2011 5:43 am
by osdevkid
Dear All,

I am receiving error for the below code

Code: Select all

#include <iostream>
using namespace std;

template <class T>
class class_template 
{
    	T value1;
		T value2;
	public:
	    class_template (T first, T second)
	    {
	      value1 = first; 
		  value2 = second;
	    }

	// public function
	T getmax()
	{			
		return value1 > value2 ? value1 : value2;
	}
};

int main()
{
	char a = 'A', b = 'B';
  	class_template <int> myobject1 (100, 75);
	class_template <int> myobject2 (123.123, 75.87); 
	class_template <float> myobject3 (123.123, 75.87);	
	class_template <char> myobject4 ('A', 10);	
	class_template <char*> myobject5 (&a, &b);
	class_template <class_template*> myobject6 ((class_template*)0x100, (class_template*)0x200);
	
  	cout << "\n Maximum Value (int)= " << myobject1.getmax();
	cout << "\n Maximum Value (int)= " << myobject2.getmax();
	cout << "\n Maximum Value (float)= " << myobject3.getmax();
	cout << "\n Maximum Value (char)= " << myobject4.getmax();	
	printf("\n Maximum Value (char*)= 0x%08X [a=0x%08X, b=0x%08X]", myobject5.getmax(), &a, &b);
	
	printf("\n Maximum Value (class_template*)= 0x%08X [a=0x%08X, b=0x%08X]", myobject6.getmax(), &myobject1, &myobject2);	
	
	cout << "\n";
	
  	return 0;	
}
For the line number 31:

Code: Select all

		class_template <class_template*> myobject6 ((class_template*)0x100, (class_template*)0x200);
I am getting the below errors, let me know why?

Code: Select all

		error: template argument 1 is invalid
		error: invalid type in declaration before ‘(’ token
		error: missing template arguments before ‘*’ token
		error: expected primary-expression before ‘)’ token
		error: missing template arguments before ‘*’ token
		error: expected primary-expression before ‘)’ token
		error: initializer expression list treated as compound expression
However, the below program is working fine without Template

Code: Select all

#include <iostream>

using namespace std;

//template <class T>
class class_template 
{
    	class_template* value1;
		class_template* value2;
		
	public:
		
		// Constructor 		
	    class_template (class_template* first, class_template* second)
	    {
	      value1 = first; 
		  value2 = second;
	    }

		// public function
		unsigned long getmax()
		{			
			return (unsigned long)(value1 > value2 ? value1 : value2);
		}
};


int main()
{
  	class_template myobject1((class_template*)0x10, (class_template*)0x20);
	class_template myobject2((class_template*)0x30, (class_template*)0x40);
	class_template myobject3(&myobject1, &myobject2);

	printf("\n Maximum Value (class_template*)= 0x%08X [a=0x%08X, b=0x%08X]", myobject3.getmax(), &myobject1, &myobject2);	
	
	cout << "\n";
	
  	return 0;	
}

/* 
output:

 Maximum Value (class_template*)= 0xBFBE87A8 [a=0xBFBE87A8, b=0xBFBE87A0]
 
*/

Re: C++ templates (error for Class own reference)...

Posted: Thu May 19, 2011 5:48 am
by qw
The "class_template" is not a type so "class_template*" is invalid. So "class_template< class_template* >" and "(class_template*)0x10" are invalid too.

For example, "class_template< class_template<int>* >" should be okay.

Re: C++ templates (error for Class own reference)...

Posted: Thu May 19, 2011 6:06 am
by osdevkid
Dear Hobbes,

You are right, the C++ compiler will not generate the class definition until you create a object with particular type for the template class.

so the "class_template" is not a standard type, so class definition is not yet generated by compiler for this type. That is why it gives error.

Please correct me, if my understanding is wrong.

Re: C++ templates (error for Class own reference)...

Posted: Thu May 19, 2011 2:11 pm
by TylerH
No, that has nothing to do with it. You're using C style casts when you need to be using C++ style casts ie "constructors."

Re: C++ templates (error for Class own reference)...

Posted: Fri May 20, 2011 12:49 am
by Solar
TylerH wrote:No, that has nothing to do with it. You're using C style casts when you need to be using C++ style casts ie "constructors."
Erm...

What?

When you're setting "constructors" in quotation marks like that and call them "C++ style casts", it gives me the impression that I shouldn't let you touch any C++ in earnest...

Hobbes was spot-on:

Code: Select all

template <class T> class class_template; // not a type, but a template.
class_template< int > foo;       // foo has a type
class_template< double > bar;    // bar has a type
class_template baz;              // syntax error

Re: C++ templates (error for Class own reference)...

Posted: Fri May 20, 2011 1:54 am
by qw
Furthermore, C-style casts do not lead to syntax errors. It may be recommendable to use static_cast and const_cast etc instead, but syntactically C-style casts are perfectly valid.

Re: C++ templates (error for Class own reference)...

Posted: Fri May 20, 2011 8:41 am
by TylerH
Solar wrote:
TylerH wrote:No, that has nothing to do with it. You're using C style casts when you need to be using C++ style casts ie "constructors."
Erm...

What?

When you're setting "constructors" in quotation marks like that and call them "C++ style casts", it gives me the impression that I shouldn't let you touch any C++ in earnest...

Code: Select all

template <class T> class class_template; // not a type, but a template.
class_template< int > foo;       // foo has a type
class_template< double > bar;    // bar has a type
class_template baz;              // syntax error
I'm refering to this:

Code: Select all

   class_template <class_template*> myobject6 ((class_template*)0x100, (class_template*)0x200);
You can't use C style casts like that. You would have to use a constructor (and new).

Code: Select all

   class_template <class_template<type here*> myobject6 (new class_template<type here>(p, q), new class_template<type here>(r, s));
No need to be an *******. I was just trying to keep it simple.
Solar wrote:Hobbes was spot-on:
I wasn't responding to Hobbes; I was responding to the most recent post.

Re: C++ templates (error for Class own reference)...

Posted: Fri May 20, 2011 9:20 am
by Solar
TylerH wrote:I'm refering to this:

Code: Select all

   class_template <class_template*> myobject6 ((class_template*)0x100, (class_template*)0x200);
You can't use C style casts like that.
No offense intended, neither in this post nor the previous one, but:

Hell yes, you can.
TylerH wrote:You would have to use a constructor (and new).

Code: Select all

   class_template <class_template<type here*> myobject6 (new class_template<type here>(p, q), new class_template<type here>(r, s));
I have no idea what you're trying to achieve, but no matter what you're barking up the wrong tree.

Replace this line in the topmost source example in the original post:

Code: Select all

   class_template <class_template*> myobject6 ((class_template*)0x100, (class_template*)0x200);
With this:

Code: Select all

   class_template <class_template<int>*> myobject6 ((class_template<int>*)0x100, (class_template<int>*)0x200);
And the program not only compiles, but runs flawlessly:

Code: Select all

 Maximum Value (int)= 100
 Maximum Value (int)= 123
 Maximum Value (float)= 123.123
 Maximum Value (char)= A
 Maximum Value (char*)= 0x0022CD4F [a=0x0022CD4F, b=0x0022CD4E]
 Maximum Value (class_template*)= 0x00000200 [a=0x0022CD44, b=0x0022CD3C]
The output is a bit nonsensical, as the last line lists the addresses of myobject1 and myobject2, which have nothing to do with myobject6.getmax() at all.
TylerH wrote:No need to be an *******. I was just trying to keep it simple.
Correctness first, simplicity second. The use of C-style casts is perfectly acceptable at that point. (A pointer to X need not actually point to a real, existing instance of type X. Check out reinterpret_cast, which is what this C-style cast actually does here.)
TylerH wrote:I wasn't responding to Hobbes; I was responding to the most recent post.
The error in osdevkid's most recent post has nothing to do with casting. Emphasis mine:
osdevkid wrote:You are right, the C++ compiler will not generate the class definition until you create a object with particular type for the template class.
You don't have to instantiate (create) an object of a given template type, you just have to instantiate the template with a given type. There's a difference in there:

Code: Select all

class_template<int> * foo = (class_template<int> *) 0xdeadbeef;
At no point does an object of type class_template<int> actually exist - we're only handling pointers to that type here. The constructor of class_template is not called in this line of code, not for T == int or any other type. But by stating that such a thing as class_template<int> exists - i.e., instantiating the template for type int - the compiler is satisfied.

Re: C++ templates (error for Class own reference)...

Posted: Sat May 21, 2011 11:17 am
by Owen
C style casts are mostly equivalent to static_cast. That said, there is no C++ style cast which behaves in exactly the same way as a C style cast - after all, if it did, it would be pointless.

Re: C++ templates (error for Class own reference)...

Posted: Sun May 22, 2011 12:24 am
by Solar
Owen wrote:That said, there is no C++ style cast which behaves in exactly the same way as a C style cast - after all, if it did, it would be pointless.
There is nothing a C cast can do that a C++ cast cannot. With the added value that C++ casts are explicit about their purpose, and can be grep'ed for. In C++, C casts are (possible but) pointless.

And actually forbidden in any C++ project where I have a say in the coding style guide, for those exact two reasons (explicitness, grep-ability).

Re: C++ templates (error for Class own reference)...

Posted: Mon May 23, 2011 4:58 am
by osdevkid
Solar wrote: You don't have to instantiate (create) an object of a given template type, you just have to instantiate the template with a given type. There's a difference in there:

Code: Select all

class_template<int> * foo = (class_template<int> *) 0xdeadbeef;
Dear Solar,

You said, to create a given template type, we don't need to create an object, I am confused, in the above code example also, you are creating a pointer object "foo" to instantiate the template type.

So, you mean creating a class pointer and creating an object both are different. A class pointer is just a pointer variable, until we allocate memory (new) for that, we can not use it to hold data defined in that class.

OK, can you give me some example to create a given template type. without creating pointer to that class or without creating object to that class? I want to know, is there any other possible ways to create a class template types without using these two methods?

Re: C++ templates (error for Class own reference)...

Posted: Mon May 23, 2011 5:50 am
by Solar
I don't think that will work, berkus. Perhaps you were thinking of 'export'?
osdevkid wrote:You said, to create a given template type, we don't need to create an object, I am confused, in the above code example also, you are creating a pointer object "foo" to instantiate the template type.
There is a significant difference in C++ between Object and Pointer to Object.

Your Object might be huge, containing megabytes of quite complex data structures. A pointer to that object is still just a 32 / 64 bit value, and it might not point to a real Object at all.
So, you mean creating a class pointer and creating an object both are different. A class pointer is just a pointer variable, until we allocate memory (new) for that, we can not use it to hold data defined in that class.
You are correct.
OK, can you give me some example to create a given template type. without creating pointer to that class or without creating object to that class? I want to know, is there any other possible ways to create a class template types without using these two methods?
Well, you could declare a pointer to the pointer to the class, for starters.

Think of it like this:

Code: Select all

template < typename T > class MyClass { /* ... */ };
In this example, MyClass is not a type, it is a template for a type, or an incomplete type if you want to put it like that. You cannot have an object of type MyClass, or a pointer to type MyClass. (Which is what the original error message told you.)

Only if you complete the type definition, by telling the compiler what type this "T" is, do you get an type.

MyClass< int > is one (complete) type, MyClass< double > is another type.

There might be several ways to state that there is such a thing as MyClass< int > (which I called "instantiating a template" above - which, I admit, is not a very precise way of calling it, but I don't know any better). Any such way will "complete" the type definition for the compiler.

It doesn't matter much how many ways there are to "instantiate a template" (unless you're writing up bogus questions for a quiz). In 95% of all cases, you'll be creating an object of that type, in 4.99% of cases you'll be creating a pointer to that type, and you shouldn't worry about the remaining 0.01% until you actually encounter them.

Re: C++ templates (error for Class own reference)...

Posted: Mon May 23, 2011 6:04 am
by osdevkid
Dear Solar,

Now I understood, thank you very much.