By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,408 Members | 1,150 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,408 IT Pros & Developers. It's quick & easy.

Stuck on partial specialization syntax, as usual.

P: n/a
I never seem to be able to get this right. Here I have some code:

template <typename T, int Nclass A {
void f (T);
};

template <typename Tvoid A<T,1>::f (T) {
}

template <typename Tvoid A<T,3>::f (T) {
}

The goal of that code is to partially specialize A<T,N>::f() for
certain values of N, leaving T unconstrained. The syntax is what I
could pick up from this site:

http://www.cprogramming.com/tutorial...alization.html

This code does not compile. Comeau (using whatever the default
settings are when you go to the test drive site) seems to produce the
clearest errors:

"ComeauTest.c", line 5: error: template argument list must match the
parameter list
template <typename Tvoid A<T,1>::f (T) {

"ComeauTest.c", line 8: error: template argument list must match the
parameter list
template <typename Tvoid A<T,3>::f (T) {

I can't seem to massage this into compiling. What is the right syntax
for this?

Thanks!
Jason
Jun 27 '08 #1
Share this Question
Share on Google+
10 Replies


P: n/a
On May 26, 1:12 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.comwrote:
This code does not compile. Comeau (using whatever the default
settings are when you go to the test drive site) seems to produce the
clearest errors:

"ComeauTest.c", line 5: error: template argument list must match the
parameter list
template <typename Tvoid A<T,1>::f (T) {

"ComeauTest.c", line 8: error: template argument list must match the
parameter list
template <typename Tvoid A<T,3>::f (T) {
Well, FWIW here is what GCC says, also (3.4.5 MinGW):

$ g++ pspec.cpp
pspec.cpp:5: error: invalid use of undefined type `class A<T, 1>'
pspec.cpp:1: error: declaration of `class A<T, 1>'
pspec.cpp:5: error: template definition of non-template `void A<T,
1>::f(T)'
pspec.cpp:8: error: invalid use of undefined type `class A<T, 3>'
pspec.cpp:1: error: declaration of `class A<T, 3>'
pspec.cpp:8: error: template definition of non-template `void A<T,
3>::f(T)'

Jason
Jun 27 '08 #2

P: n/a
ja************@gmail.com wrote:
I never seem to be able to get this right. Here I have some code:

template <typename T, int Nclass A {
void f (T);
};

template <typename Tvoid A<T,1>::f (T) {
}
You can't partially specialise an individual member of class template.

--
Ian Collins.
Jun 27 '08 #3

P: n/a
Thanks for your reply.

On May 26, 1:43 am, Ian Collins <ian-n...@hotmail.comwrote:
jason.cipri...@gmail.com wrote:
I never seem to be able to get this right. Here I have some code:
template <typename T, int Nclass A {
void f (T);
};
template <typename Tvoid A<T,1>::f (T) {
}

You can't partially specialise an individual member of class template.

:-(

So... if most compilers optimize away constant conditions; can I do
something like this instead:

template <typename T, int Nvoid A<T,N>::f (T) {
if (N == 1) {
} else if (N == 3) {
}
}

And (probably) not take a performance hit?

Thanks,
Jason
Jun 27 '08 #4

P: n/a
In article <d2ead088-61cc-4658-9c32-b4bedf22bd04@
59g2000hsb.googlegroups.com>, ja************@gmail.com says...
I never seem to be able to get this right. Here I have some code:

template <typename T, int Nclass A {
void f (T);
};
This is a class template.
template <typename Tvoid A<T,1>::f (T) {
}
This is an attempt at only the member function for a partially
specialized class template -- you need to start with the partial
specialization of the class template itself. Unlike inheritance (for one
example), partial specialization doesn't imply anything about the
partially specialized template having a structure similar to the
unspecialized template. They typically share (at least most of) the same
member functions, but you need to redeclare and re-define each member
function in every partial specialization. The language doesn't prevent
you from defining entirely different member functions in each partial
specialization, if you so choose.

template <class T, int N>
struct A {
void f(T) { std::cout << "Unspecialized.\n"; }
};

template <class T>
struct A<T, 1{
void f(T) { std::cout << "Spec 1\n"; }
};

template <class T>
struct A<T, 2{
void f(T) { std::cout << "Spec 2\n"; }
};

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #5

P: n/a
Thanks for your reply.
>
On May 26, 1:43 am, Ian Collins <ian-n...@hotmail.comwrote:
>jason.cipri...@gmail.com wrote:
>>I never seem to be able to get this right. Here I have some code:
template <typename T, int Nclass A {
void f (T);
};
template <typename Tvoid A<T,1>::f (T) {
}
You can't partially specialise an individual member of class template.


:-(

So... if most compilers optimize away constant conditions; can I do
something like this instead:

template <typename T, int Nvoid A<T,N>::f (T) {
if (N == 1) {
} else if (N == 3) {
}
}

And (probably) not take a performance hit?
template <typename T, int N>
class A {
void f(T);
};

template<typename T>
class A1: public A<T,1{};

template<typename T>
void A<T,1>::f(T) { /* ... */ }
Jun 27 '08 #6

P: n/a
On May 26, 1:51 am, Jerry Coffin <jcof...@taeus.comwrote:
This is an attempt at only the member function for a partially
specialized class template -- you need to start with the partial
specialization of the class template itself. Unlike inheritance (for one
example), partial specialization doesn't imply anything about the
partially specialized template having a structure similar to the
unspecialized template.
Thanks.

In my case, I have a fairly large and complex template class, but a
small handful of the member functions can be highly optimized for
certain template parameters. I'll have to rethink my design a little
and somehow split things up a little differently; it's very
inconvenient to have to maintain two copies of the code.

I'm almost considering hacking something together right now like:

--- template.h ---

template <class T>
struct A<T, SPECVAL{
void f(T) { std::cout << "Spec 1\n"; }
};

--- otherfile.h ---

#define SPECVAL 1
#include "template.h"
#undef SPECVAL
#define SPECVAL 2
#include "template.h"

---

I have a feeling that may make me some enemies some day. Too bad I
have a deadline in the morning :-(.

Thanks,
Jason
Jun 27 '08 #7

P: n/a
ja************@gmail.com wrote:
Thanks for your reply.

On May 26, 1:43 am, Ian Collins <ian-n...@hotmail.comwrote:
>jason.cipri...@gmail.com wrote:
>>I never seem to be able to get this right. Here I have some code:
template <typename T, int Nclass A {
void f (T);
};
template <typename Tvoid A<T,1>::f (T) {
}
You can't partially specialise an individual member of class template.
:-(

So... if most compilers optimize away constant conditions; can I do
something like this instead:

template <typename T, int Nvoid A<T,N>::f (T) {
if (N == 1) {
} else if (N == 3) {
}
}

And (probably) not take a performance hit?
Or try another level of indirection along the lines of:

#include <iostream>

template <typename T, int Nclass A
{
template <int NNstruct X{};

template <typename TTvoid fn( T t, TT )
{
std::cout << "called for " << N << std::endl;
}

void fn( T t, X<1)
{
std::cout << "specialised for 1" << std::endl;
}

public:

void f(T t)
{
fn( t, X<N>() );
}
};

int main()
{
A<int, 42>().f( 0 );
A<int, 1>().f( 0 );

return 0;
}

--
Ian Collins.
Jun 27 '08 #8

P: n/a
On May 26, 2:44 am, Ian Collins <ian-n...@hotmail.comwrote:
Or try another level of indirection along the lines of:
That's pretty clever; thanks!

Jason
Jun 27 '08 #9

P: n/a
On May 26, 7:48 am, "jason.cipri...@gmail.com"
<jason.cipri...@gmail.comwrote:
Thanks for your reply.
On May 26, 1:43 am, Ian Collins <ian-n...@hotmail.comwrote:
jason.cipri...@gmail.com wrote:
I never seem to be able to get this right. Here I have some code:
template <typename T, int Nclass A {
void f (T);
};
template <typename Tvoid A<T,1>::f (T) {
}
You can't partially specialise an individual member of class template.
:-(
So... if most compilers optimize away constant conditions; can I do
something like this instead:
template <typename T, int Nvoid A<T,N>::f (T) {
if (N == 1) {
} else if (N == 3) {
}
}
And (probably) not take a performance hit?
Probably. The usual solution is to use a helper function and a
discriminator class, something like:

template< typename T, int N class A {
{
template< int N >
class Discriminator;

void f( T t ) {
{
f( t, Discriminator< N >() ) ;
}

void f( T t, Discriminator<1) {
// specialization for 1...
}
void f( T t, Discriminator<3) {
// specialization for 3...
}
} ;

Presumably, because it is the standard idiom, compilers will
recognize it, and not generate any extra code for the unused
argument (at least as long as the functions are inline).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #10

P: n/a
In article <21085279-b67d-44f1-a883-fce64b362eb5@
2g2000hsn.googlegroups.com>, ja************@gmail.com says...

[ ... ]
In my case, I have a fairly large and complex template class, but a
small handful of the member functions can be highly optimized for
certain template parameters. I'll have to rethink my design a little
and somehow split things up a little differently; it's very
inconvenient to have to maintain two copies of the code.
It sounds like Ian Collins's suggestion fits your situation almost
perfectly.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jun 27 '08 #11

This discussion thread is closed

Replies have been disabled for this discussion.