PDA

View Full Version : C++ class templates in XCode (10.5)




Sean7512
Feb 2, 2008, 05:54 PM
Hello all, I have a quick question about XCode. I am working on my Data Structures homework, which was to create a class template with some functions in C++, and then to test the template with both a float and a struct (that we made in class). I have finished the assignment, but I am unable to compile it. So I was wondering, how should my files be in my XCode project? I know in Visual Studio you are not to include the class implementation file into the project. I have tried both ways, and continue to get errors (all of which occur in the class implementation file). So, I am certain that I am not setting this up correctly.

If it helps, I can compress the folder to post here or I can just post my 3 source files (1 header, and 2 .cpp's), just let me know.

Thanks in advance!!!

Sean

Edit:
Silly me, I forgot to post the error that I get...
In the class implementation file, above each function definition there is the "template<class DataType>" line, and that is where the error occurs for all of the class definitions, and the error is "Expected initializer before '<' token"



Cromulent
Feb 2, 2008, 06:12 PM
A bit of code would help :).

Sean7512
Feb 2, 2008, 06:17 PM
Well, since I do not get any errors in my header or my code with main() in it, I will just post the class implementation file for now...

Hope that may help! As you can see, it is a VERY small exercise from our book, haha.

Edit: It would probably make sense to post my header file for the class, hang on, I'll add it

omikjam
Feb 2, 2008, 09:56 PM
template<class DataType>
class Rectangle
{
public:
void setWidth(DataType someWidth);
void setLength(DataType someLength);
bool lengthGreaterThanWidth();
DataType getPerimeter();
DataType getArea();

private:
DataType width;
DataType length;
DataType perimeter;
DataType area;
}; <-- pretty sure you need to add the semicolon there

- Just another noobie here trying to be helpful :)

wmccurdy53
Feb 2, 2008, 10:31 PM
[code]
template<class DataType>
snip...



Change:
template<class DataType>
To:
template<typename DataType>

Sean7512
Feb 3, 2008, 01:04 AM
template<class DataType>
class Rectangle
{
public:
void setWidth(DataType someWidth);
void setLength(DataType someLength);
bool lengthGreaterThanWidth();
DataType getPerimeter();
DataType getArea();

private:
DataType width;
DataType length;
DataType perimeter;
DataType area;
}; <-- pretty sure you need to add the semicolon there

- Just another noobie here trying to be helpful :)

Ahh, stupid me! I am not sure how I missed that! Thanks a bunch, it now works fine!

If anyone is wondering that doesn't know, when working with class templates in XCode, you have to have the class implementation file in the project folder BUT not included in your XCode project. It is the same way in Visual Studio as well.

Soulstorm
Feb 3, 2008, 05:31 AM
Actually, the way you have it set up will not work. And if it does, it will cause you problems later.

You tend to disobey the rules of implementing header files in your computer. Both template definitions and implementations must exist in the same file, that means that you must write in the header files both the implementation and definition of the template. It won't work otherwise. And that happens only with the templates and it is just a thing with them, you have to accept it. That's your first mistake, right there.

Your second mistake is the inclusion of the implementation file in your header file. When you include a header file, the compiler will include it in the project, and will also search for any implementation files in the project. If not found, only the header file is included. If you include the implementation file in your header file, you will come across errors of multiple definitions and implementations.

My suggestions:
1) Write any templates in the same files, do not use separate files for each, as you will later need to use workarounds that will definitely result in errors that may seem irrelevant to this, but will have this as the cause of the problem.
2) Do not include any .cpp file in an .h file. Ever. Only include .h files in each file, and the compiler will handle the rest.
3)Use the compiler preprocessor with #ifdef, #ifndef, #define. If you don't know how to use those, it's time to learn.

I am saying all this, because I made the same mistakes at some point, and I spent entire days trying to figure out what was wrong.

I hope I helped.

Sean7512
Feb 3, 2008, 10:33 AM
Actually, the way you have it set up will not work. And if it does, it will cause you problems later.

You tend to disobey the rules of implementing header files in your computer. Both template definitions and implementations must exist in the same file, that means that you must write in the header files both the implementation and definition of the template. It won't work otherwise. And that happens only with the templates and it is just a thing with them, you have to accept it. That's your first mistake, right there.

Your second mistake is the inclusion of the implementation file in your header file. When you include a header file, the compiler will include it in the project, and will also search for any implementation files in the project. If not found, only the header file is included. If you include the implementation file in your header file, you will come across errors of multiple definitions and implementations.

My suggestions:
1) Write any templates in the same files, do not use separate files for each, as you will later need to use workarounds that will definitely result in errors that may seem irrelevant to this, but will have this as the cause of the problem.
2) Do not include any .cpp file in an .h file. Ever. Only include .h files in each file, and the compiler will handle the rest.
3)Use the compiler preprocessor with #ifdef, #ifndef, #define. If you don't know how to use those, it's time to learn.

I am saying all this, because I made the same mistakes at some point, and I spent entire days trying to figure out what was wrong.

I hope I helped.

I wrote my files exactly the way that our book says to. The book AND teacher said that for a class template file, you MUST include the .cpp file at the END of the .h file. I am just going by what the teacher tells me or I lose points. It does work fine, so I did something right. For a normal class, ya, you include all files in your project and in the .cpp you include he .h and you don't include the .cpp in the header. The book goes into a lengthy explanation on why this won't work for a class template.

Anyways, I appreciate your input, but I am going by the book, because I don't want to lose points :)

Edit:
Later tonight, when I have time, I will copy in exactly what my text book says on the matter. Maybe we can turn this into a discussion? haha BTW, my book for class is this one http://www.amazon.com/C-Classes-Structures-Jeffrey-Childs/dp/0131580515

iSee
Feb 3, 2008, 11:30 AM
The way you (Sean7512) have the files set up will work, but it is wacky.

Like SS says, for template classes, the implementation must be part of the header file. Your project accomplishes that by the #include "<the implementation file>"

I think it's fine to split the template class declaration and implementation into two separate files.

The problem, is that the implementation file has a .cpp extension. However it is not a .cpp file. It is actually an extension of the template declaration header file--that is, it is a header file itself. That is why you can't add it to the project--it can't be compiled as a real .cpp file.

What people do in the real world in this situation is to name the files something like this:

RectangleT.h (the Rectangle template declaration)
RectangleTImpl.h (the Rectangle template implementation)

Where RectangleT.h includes RectangleTImpl.h.

The included implementation file has the correct .h extension, and the Impl suffix makes it clear that it contains the implementation of Rectangle. Different people use different suffixes or extensions for the implementation file, but the point is to not use .cpp, which means something else.

Anyway, this is all moot. If I were you, I too would use the method your professor prefers... but only as long as that class lasts.

Soulstorm
Feb 6, 2008, 09:41 AM
I wrote my files exactly the way that our book says to. The book AND teacher said that for a class template file, you MUST include the .cpp file at the END of the .h file. I am just going by what the teacher tells me or I lose points. It does work fine, so I did something right. For a normal class, ya, you include all files in your project and in the .cpp you include he .h and you don't include the .cpp in the header. The book goes into a lengthy explanation on why this won't work for a class template.

Anyways, I appreciate your input, but I am going by the book, because I don't want to lose points

I see. Well, as you may learn when progressing deeper into programming concepts, when programming is the main theme for discussion, not every professor knows what he's talking about. Probably, the professor just bought the book, studied only from that, and thinks this is the best way of programming.

I would do what my professor says. However, I would abandon that coding style afterwards. As with your book, I have also a lengthy explanation of why you shouldn't write things this way, but all my explanations involve terms and concepts I think you are not ready to dive into yet.

So, just do this: Follow your teacher to the letter. When this class ends, look into the internet, and read better on templates, compiler optimization methods and performance. And you will figure everything out.

Sean7512
Feb 7, 2008, 09:32 PM
I see. Well, as you may learn when progressing deeper into programming concepts, when programming is the main theme for discussion, not every professor knows what he's talking about. Probably, the professor just bought the book, studied only from that, and thinks this is the best way of programming.

I would do what my professor says. However, I would abandon that coding style afterwards. As with your book, I have also a lengthy explanation of why you shouldn't write things this way, but all my explanations involve terms and concepts I think you are not ready to dive into yet.

So, just do this: Follow your teacher to the letter. When this class ends, look into the internet, and read better on templates, compiler optimization methods and performance. And you will figure everything out.

Could you please tell me, the explanation? I am in my last semester of computer classes, and I have an internship with a company developing software for the military(C#), I am fairly certain that I am ready for the explanation, as our group of interns (4 people) have successfully finished two projects for the army that are actually being used in the field, which is a great feeling :)

This assignment was a review, because we haven't took c++ since freshman year. Anyways, I told my teacher, and she said that she knows that its possible to do it other ways, but that the department head wants everything to be taught consistently so that the different teachers in the department are all on the same page when writing example programs, etc.

Thanks a lot, everyone!

Soulstorm
Feb 10, 2008, 10:18 AM
OK:

When you write at the preprocessor the "#include" directive, you actually tell the compiler to copy every text that this file includes, and paste it into the file in the place of the #include directive.

If you place the #include directive for a .cpp file at the end of an .h file, you actually tell it to include the .cpp file, and paste it below the definition file. The teacher probably told you to do this as a workaround for the problem that exists with C++ templates that are not included automatically if not places entirely (both definition and implementation) inside the same file.

Normally for a human, this is absolutely correct. However, the way most universal compilers are set to work, (like GCC) is: when you include an .h file the compiler also searches for a file with the same name but with another ending (.m, .cpp, .c, you name it) and actually pastes this files text into the header file, and pastes the newly created header file into the file you have written the #include directive. This happens when you have NOT written any #include directive to the end of a header file.

As you can see, the thing you are doing while doing the thing I told you not to do ( :) ) is predefined and will normally be this way. So, problems may arise by only doing manually something that a compiler would normally do.

But that is the least of your concerns.

I suspect you know the #ifndef, #ifdef etc preprocessor commands. If you do, you would have known that the best use for them is to put them into the header file and not the implementation file. That way, when the compiler includes the file (using the method described above) it also verifies that this header file (and consequently, the implementation file) will not be included more than once (read about the one-definition-rule).

But if you start including implementation files manually with the #include directive, this will result in multiple definitions or multiple implementations, as in larger projects, you will most likely forget including something. Not to mention that many compilers will complain about including directives that include both the implementation and header files, which will result in a disaster.

As you can see, the method you want to use is not standard. And since it's not, you will deal with problems sooner or later.So, when dealing with templates, please write them all in a header file (.hh) and include only that.

gnasher729
Feb 10, 2008, 11:00 AM
The usual distinction is: .cpp = C++ source code, will be compiled and the compiled code included in the project. .h = header file, contains declarations, especially declarations used by users of the C++ file. And the C++ file usually includes a .h file with the same name as the very first thing.

In this case, putting the template implementation into a file named .cpp just causes confusion. It won't be compiled and the compiled code included in the project. It doesn't include the .h file. It is included by the .h file. It contains C++ source code, but it isn't a C++ source file. Tools might get confused (for example an automated build system that thinks every .cpp file is a source file). Much better to call it something.impl.h or similar.