C++ Template Issues

By (6 posts) on August 29, 2006 at 9:04 pm

Typename compliance

Defining a method with signature:

bool Swap(vector<T>::iterator a, vector<T>::iterator b);

Results in the following output with VS2005 and VS.net 2003 (maybe vc7.0?):

warning C4346: 'std::vector<T>::iterator' : dependent name is not a type prefix with 'typename' to indicate a type

This syntax isn't standard C++ compliant. The warning does a good job of helping out, but some still have trouble interpretting compiler warnings and output. The older MS compilers allowed this syntax, to get around stricter ISO compliance, simply add the typename qualifier as shown:

bool Swap(typename vector<T>::iterator a, typename vector<T>::iterator b);

That does it!

Template Implementation Location

When developing template code, when methods are call from without the implementation file, the implementation will be unresolved when linking.

templatetest.h

template<class T> class Test

{

public:

int Count();

};

templatetest.cpp

include "templatetest.h"

template<class T> Test::Count()

template<class T> int Test<T>::Count()

{

return 1;

}

main.cpp

include "templatetest.h"

void main()

{

Test<char> MyTest;

MyTest.Count();

}

This will result in:

error LNK2001: unresolved external symbol "public: int __thiscall Test<class char>::Count(void)"

The most common solution to this as in STLPort and the Microsoft STL is to include the implementation within the header file itself. If however, you wish to separate the interfaces from the implementation, another header file could be created, templatetest.impl.h and included from within the original header file, templatetest.h. This is what I like doing:

templatetest.h

template<class T> class Test

{

public:

int Count();

};

include "templatetest.impl.h"

templatetest.impl.h

template<class T> Test::Count()

template<class T> int Test<T>::Count()

{

return 1;

}

main.cpp

include "templatetest.h"

void main()

{

Test<char> MyTest;

MyTest.Count();

}

Just remember to include the implementation header last so that all the classes are declared ahead of time.

Categories: Mobility

Comments (9) Comments RSS Feed

By mbartosik@yahoo.com on September 19th, 2006 at 7:27 pm
If you want to be able to have the template implementation for any type T in a separate .cpp file then you need a compiler that implements the C++ keyword 'export'. To my knowledge the current state of the art is that at most one compiler on the planet implements 'export'.

You can provide an implementation for a concrete type in a .cpp file using template specialization, but that's not usually what you want (typically you want an implementaiton for a generic type T).

So separating the implementation into file.impl.h or file_impl.hpp or whatever naming scheme you like is currently the best solution for most compilers.

I have also heard that the key word 'export' is very low on most compiler vendors todo lists (appearently it is real hard to implement).

By alokgovil@hotmail.com on September 20th, 2006 at 4:45 am
C++ committee should never have added 'export' keyword without thinking enough on possible means for compiler vendors to implement it. They say that C++ standards committee only devices the standard, implementation is purely a business of the compiler vendors since implementations can be different. Yet, I see no point adding a keyword to the language requires implementation to totally revamp the compiler source code as well as potentially the run-time execution engine*! And even if they were to do it, the various implementations could become so different from each other internally that they should not be advertized as just a C++ compliant compiler! [* Curiously, the latter is what Microsoft did with .NET generics, and they then 'can' do what export keyword is supposed to do in C++.]

Best regards - Alok Govil

By Shawn Casey on September 20th, 2006 at 4:27 pm
mbartosik,
Funny enough, I just added two of Herb Sutter's books (Exceptional C++, Exceptional C++ Style) to my library and in the later, I just read about the export solution (Item 10), but as both you and alokgovil have mentioned, compiler support is spotty. He mentions Comeau 4.3.01 (2002) being the only compiler to support it today. I don't think it's a big deal to split the implementation into different files as mentioned above.

By fzlbqiang@hotmail.com on September 27th, 2006 at 1:45 am
i think you made a mistake, in my Visual C++ 6.0, generate the following error:
template_testtemplatetest.h(10) : error C2955: 'test' : use of class template requires template argument list
e:visual studio 6.0 projecttemplate_testtemplatetest.h(8) : see declaration of 'test'
Error executing cl.exe.

main.obj - 1 error(s), 0 warning(s)

and i find the following code is the problem:

templatetest.cpp

include "templatetest.h"

template<class T> Test::Count()

{

return 1;

}

must modify as:

templatetest.cpp

include "templatetest.h"

template<class T> Test<T>::Count()

{

return 1;

}

By fzlbqiang@hotmail.com on September 27th, 2006 at 1:48 am
i think you made a mistake:

template<class T> test<T>::count()
{
return 1;
}

not
template<class T> test::count()
{
return 1;
}

By fzlbqiang@hotmail.com on September 27th, 2006 at 1:53 am
the correction is :

template<class T> int test<T>::count()
{
return 1;
}

sorry , i cannot delete the comments.

By Shawn Casey on October 3rd, 2006 at 5:38 am
fzlbqiang,
You are correct, good catch. I'll modify the article. I should've run it through the compiler. :)

By Veikko Eeva on November 12th, 2006 at 1:37 pm
I think one great problem with the keyword "export" is related to the compilation model C/C++ has. If I remember correctly some of the comments made by one ofthe Edison Design Group, and consequently, EDG C++ parser front end makers Daveed Vandevoorde, they had to "guess" some parts of the standards since there were some functionality required that was not defined.

I guess the commitee got a bit wiser on adding features that aren't truly tried and tested after this one. There is some pondering on the issue here, for instance:
http://www.ddj.com/dept/cpp/184401563

By Veikko Eeva on November 12th, 2006 at 1:44 pm
I think one great problem with the keyword "export" is related to the compilation model C/C++ has. If I remember correctly some of the comments made by one ofthe Edison Design Group, and consequently, EDG C++ parser front end makers Daveed Vandevoorde, they had to "guess" some parts of the standards and cut around corners, since there were some functionality required that was not defined.

I guess the commitee got a bit wiser on adding features that aren't truly tried and tested after this one. There is some pondering on the issue here, for instance:
http://www.ddj.com/dept/cpp/184401563


What do you think?

Name (required)

Email (required; will not be displayed on this page)

Your URL (optional)

Comments (required)