Template specializations

I

Immortal Nephi

If I want to create template specializations, then I create one class
before I define data type in T. My question is – can int size have
specializations such as char size or short size? The data type will
be determined at compile-time.

template< typename T, int size > // char size or short size?
class Test {
};

template
class Test< char , 10 >;

template
class Test< short , 10 >;

template
class Test< long , 10 >;
 
S

Stuart Golodetz

Immortal said:
If I want to create template specializations, then I create one class
before I define data type in T. My question is – can int size have
specializations such as char size or short size? The data type will
be determined at compile-time.

template< typename T, int size > // char size or short size?
class Test {
};

template
class Test< char , 10 >;

template
class Test< short , 10 >;

template
class Test< long , 10 >;

Do you want something like this by any chance?

template <typename T, T size> struct X {};
template <char size> struct X<char,size> {};
template <short size> struct X<short,size> {};
// etc.

Regards,
Stu
 
I

Immortal Nephi

Do you want something like this by any chance?

template <typename T, T size> struct X {};
template <char size> struct X<char,size> {};
template <short size> struct X<short,size> {};
// etc.

Yes, "template <typename T, T size> struct X {};" will work that way,
but you confuse me –

template <char size> struct X<char,size> {};
template <short size> struct X<short,size> {};

C++ Compiler will fail to compile -- ???


"template <typename T, T size> struct X {};" is located in header
file. I want to define member function body in source code. How do I
explicit class?

C++ Compiler will compile fine, but shows error linking.

You need to add before linkage will work.

template struct X<char, 1 >;

However, if you try to define “X< char, 5 > _x” in main function body,
you will get error linking message because C++ Compiler is unable to
find constant size match. If you add “template struct X<char, 5 >” in
source code, linkage will work fine.

How can I create constant variable for compile-time checking.
 
F

Francesco S. Carta

Yes, "template<typename T, T size> struct X {};" will work that way,
but you confuse me –

template<char size> struct X<char,size> {};
template<short size> struct X<short,size> {};

C++ Compiler will fail to compile -- ???

No, the last two above should compile fine - those are specializations
of the general template and, strictly speaking, they aren't needed.

If your general template doesn't fit well for all the possible types it
accepts, then you can manage different types with different
implementations by defining such specializations.
"template<typename T, T size> struct X {};" is located in header
file. I want to define member function body in source code. How do I
explicit class?

C++ Compiler will compile fine, but shows error linking.

If you're trying to separate template declarations from their
implementations be aware that you cannot - unless you have a compiler
that supports exported templates, otherwise you need to put the
definition in the header file. This is one aspect of the C++ Standard
that has not been widely implemented yet and that very likely never will be.
You need to add before linkage will work.

template struct X<char, 1>;

This is an explicit instantiation and I don't think you need it.
However, if you try to define “X< char, 5> _x” in main function body,
you will get error linking message because C++ Compiler is unable to
find constant size match. If you add “template struct X<char, 5>” in
source code, linkage will work fine.

This is strange, the line above (adding a semicolon at its end) should
work fine (without any explicit instantiation) in the depicted context,
but since the context is garbled you would be better posting the full
exact code that your compiler is rejecting - or an equivalent reduction
of the same.
How can I create constant variable for compile-time checking.

I am not able to fully understand what you are asking for.

Static asserts can be implemented using some tricks with templates, they
have been implemented "independently" (it's not that hard once you
understand the mechanism) and they also have been somewhat "formalized"
into the boost library.

Make some search for "boost static_assert" and for "boost enable_if" and
you should find some strings to follow and get further informations -
some of this could be already in your implementation in some "tr"
namespace, and some of this should be part of the next C++ Standard.
 
I

Immortal Nephi

No, the last two above should compile fine - those are specializations
of the general template and, strictly speaking, they aren't needed.

If your general template doesn't fit well for all the possible types it
accepts, then you can manage different types with different
implementations by defining such specializations.





If you're trying to separate template declarations from their
implementations be aware that you cannot - unless you have a compiler
that supports exported templates, otherwise you need to put the
definition in the header file. This is one aspect of the C++ Standard
that has not been widely implemented yet and that very likely never will be.





This is an explicit instantiation and I don't think you need it.




This is strange, the line above (adding a semicolon at its end) should
work fine (without any explicit instantiation) in the depicted context,
but since the context is garbled you would be better posting the full
exact code that your compiler is rejecting - or an equivalent reduction
of the same.

No, it does not. It will only work if you place all member functions
in header file because C++ Compiler will determine size at compile-
time before linkage will work.
C++ Compiler is unable to match size in source code because size
information does not exist in object code unless you have to
explicitly define size information individually.

// template.h
template< typename T, T size >
class Object {
public:
Object( T value );
~Object();

void Print();

T data[ size ];
};


// template.cpp
template< typename T, T size >
Object< T, size >::
Object( T value ) {
data[ 0 ] = value;
}

template< typename T, T size >
Object< T, size >::
~Object() {
}

template< typename T, T size >
void Object< T, size >::
Print() {
printf( "Data: %02X Size: %d\n", data[ 0 ], size );
};

template
class Object< unsigned char, 1 >; // how to fix linking error?


// if you comment two lines below, linkage will fail.
template
class Object< unsigned char, 2 >; // linkage works fine.


// main.cpp
#include <cstdio>

int main() {
unsigned char data = 0x41;

Object< unsigned char, 1 > x( data );
x.Print();

Object< unsigned char, 2 > x( data ); // error linking message
x.Print();

return 0;
}
 
T

tni

That's a partial template specialization. Some old/broken compilers
don't support them.
If you're trying to separate template declarations from their
implementations be aware that you cannot - unless you have a compiler
that supports exported templates, otherwise you need to put the
definition in the header file.

Not completely true.
This is an explicit instantiation and I don't think you need it.

That's exactly, how you you separate template declaration / definition.

Put the definition into the header file and have a single translation
unit with the template implementation and explicit instantiations for
all the types you need (obviously only works if you can modify the
template implementation file).
 
J

Juha Nieminen

Immortal Nephi said:
It will only work if you place all member functions
in header file because C++ Compiler will determine size at compile-
time before linkage will work.

What do member functions have anything to do with the size of anything?
Member functions do not affect the size of classes or anything else.

(Ok, that's strictly speaking not true: If a class has no virtual
functions and you add one, then that will usually increase the size of
the class by the size of a pointer. However, the total amount of member
functions, virtual or not, has nothing to do with any size.)
 
F

Francesco S. Carta

That's a partial template specialization. Some old/broken compilers
don't support them.


Not completely true.


That's exactly, how you you separate template declaration / definition.

Put the definition into the header file and have a single translation
unit with the template implementation and explicit instantiations for
all the types you need (obviously only works if you can modify the
template implementation file).

Sorry, correctly explaining my point wasn't exactly easy due to the fact
that, in layman terms, templates have two definitions: the one we write
and all those that the compiler generates after the instantiation
requests: actually, the latter should be called instantiations, if I'm
not mistaken, and my point was about their definitions and not about
their instantiations.

One cannot separate the template definition from the code that uses it
to instantiate the template itself (export keyword apart, once more),
and of course one can very well instantiate it for the required types
and "put them apart" as you've explained, but then part of the
"templates" concept gets somehow defeated.
 
F

Francesco S. Carta

No, it does not. It will only work if you place all member functions
in header file because C++ Compiler will determine size at compile-
time before linkage will work.
C++ Compiler is unable to match size in source code because size
information does not exist in object code unless you have to
explicitly define size information individually.

I know, that's what I meant to say with my whole post. As I said, the
context was garbled - at least for me - and when I said "it should work"
I intended the context to be "including full definitions in the header".

I could have failed to fully recognize the actual context, that's sure,
but reading again the whole thread that doesn't surprise me at all -
missing the further follow-ups I would be posting more or less the same
words, although I recognize I could have explained my point (about
explicit instantiations) in a better way.
 
F

Francesco S. Carta

I know, that's what I meant to say with my whole post.

No, not exactly. Actually I would have spoken about missing definitions
and not about size, but that has been already pointed out by Juha.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top