468,121 Members | 1,500 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,121 developers. It's quick & easy.

Forward declarations, templates, and typedefs

I have something like the following:

template<ENUM X, int I = 0>
class Generic
{
....
};

typedef Generic<Val1> v1_type;
typedef Generic<Val2> v2_type;
typedef Generic<Val2, 1> incompat_v2_type;

I'm going to be making this class fundamental to the nature of a rather
large project (the goal is to start using it everywhere instead of
something that is currently done). I don't want to have to include the
header every time I have to return a value of this type. I want to
forward declare in headers and include in source files.

class v1_type; does not work.

I'm not that great with templates and don't fully grasp the subtleties
of what I am trying to accomplish. Can I forward declare this template
and use it? I would prefer to do so based on the typedefs, not the
actual template.

May 2 '06 #1
7 5334
Noah Roberts wrote:
I have something like the following:

template<ENUM X, int I = 0>
class Generic
{
...
};

typedef Generic<Val1> v1_type;
typedef Generic<Val2> v2_type;
typedef Generic<Val2, 1> incompat_v2_type;

I'm going to be making this class fundamental to the nature of a
rather large project (the goal is to start using it everywhere
instead of something that is currently done). I don't want to have
to include the header every time I have to return a value of this
type. I want to forward declare in headers and include in source
files.

class v1_type; does not work.

I'm not that great with templates and don't fully grasp the subtleties
of what I am trying to accomplish. Can I forward declare this
template and use it? I would prefer to do so based on the typedefs,
not the actual template.


Forward-declaring a template is just like forward-declaring anything
else, you just omit the "{..}" part:

template<ENUM X, int I> class Generic;

(now, I am not sure about the default argument, you might want to give
it a try as well).

As to "using" it, you didn't say what that means.

As to "based on the typedefs", I am not sure what you mean. Please
post more code.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
May 2 '06 #2
Noah Roberts wrote:
I have something like the following:

template<ENUM X, int I = 0>
class Generic
{
...
};

typedef Generic<Val1> v1_type;
typedef Generic<Val2> v2_type;
typedef Generic<Val2, 1> incompat_v2_type;

I'm going to be making this class fundamental to the nature of a rather
large project (the goal is to start using it everywhere instead of
something that is currently done). I don't want to have to include the
header every time I have to return a value of this type. I want to
forward declare in headers and include in source files.

class v1_type; does not work.

I'm not that great with templates and don't fully grasp the subtleties
of what I am trying to accomplish. Can I forward declare this template
and use it? I would prefer to do so based on the typedefs, not the
actual template.


You can't forward-declare a typedef because it is just an alias for
some other type, not a type itself. You can forward declare a class
template as such:

template<class T> class SomeClassTemplate;

But, to forward declare a class template with default parameters, you
have to specify them in the forward declaration:

template<ENUM X, int I = 0> class Generic;

Then you can include perhaps just your typedefs. You'll end up with
something like this:

enum ENUM { A, B };

template<ENUM X, int I = 0> class Generic;

typedef Generic<A> SomeTypeA;
typedef Generic<B> SomeTypeB;
typedef Generic<A,1> SomeTypeBad;

SomeTypeA* pa = 0;
SomeTypeB* pb = 0;
SomeTypeBad* pbad = 0;

template<ENUM X, int I = 0> class Generic
{
public:
enum { val = I };
ENUM foo() const { return X; }
};

Cheers! --M

May 2 '06 #3

mlimber wrote:
I'm not that great with templates and don't fully grasp the subtleties
of what I am trying to accomplish. Can I forward declare this template
and use it? I would prefer to do so based on the typedefs, not the
actual template.


You can't forward-declare a typedef because it is just an alias for
some other type, not a type itself. You can forward declare a class
template as such:

template<class T> class SomeClassTemplate;

But, to forward declare a class template with default parameters, you
have to specify them in the forward declaration:

template<ENUM X, int I = 0> class Generic;

Then you can include perhaps just your typedefs. You'll end up with
something like this:

enum ENUM { A, B };

template<ENUM X, int I = 0> class Generic;

typedef Generic<A> SomeTypeA;
typedef Generic<B> SomeTypeB;
typedef Generic<A,1> SomeTypeBad;

SomeTypeA* pa = 0;
SomeTypeB* pb = 0;
SomeTypeBad* pbad = 0;

template<ENUM X, int I = 0> class Generic
{
public:
enum { val = I };
ENUM foo() const { return X; }
};


So actually it might be best to create an "interface" header that had
the forward declaration and the typedefs and include it in the headers
of the clients. Then include the actual definition in sources.

I like templates but getting rid of the compile time dependencies with
them can be tough...

May 2 '06 #4
Noah Roberts wrote:
mlimber wrote:
I'm not that great with templates and don't fully grasp the subtleties
of what I am trying to accomplish. Can I forward declare this template
and use it? I would prefer to do so based on the typedefs, not the
actual template.
You can't forward-declare a typedef because it is just an alias for
some other type, not a type itself. You can forward declare a class
template as such:

template<class T> class SomeClassTemplate;

But, to forward declare a class template with default parameters, you
have to specify them in the forward declaration:

template<ENUM X, int I = 0> class Generic;

Then you can include perhaps just your typedefs. You'll end up with
something like this:

enum ENUM { A, B };

template<ENUM X, int I = 0> class Generic;

typedef Generic<A> SomeTypeA;
typedef Generic<B> SomeTypeB;
typedef Generic<A,1> SomeTypeBad;

SomeTypeA* pa = 0;
SomeTypeB* pb = 0;
SomeTypeBad* pbad = 0;

template<ENUM X, int I = 0> class Generic
{
public:
enum { val = I };
ENUM foo() const { return X; }
};


So actually it might be best to create an "interface" header that had
the forward declaration and the typedefs and include it in the headers
of the clients. Then include the actual definition in sources.


If the forward declaration and typedefs are used widely, then sure.
I like templates but getting rid of the compile time dependencies with
them can be tough...


Sometimes it's impossible. For instance, you can't (portably)
forward-declare STL containers such as std::vector since
implementations are permitted to attach as many extra template
parameters as they like, so long as they're given defaults.

Cheers! --M

May 2 '06 #5
mlimber wrote:
Noah Roberts wrote:
I like templates but getting rid of the compile time dependencies with
them can be tough...


Sometimes it's impossible. For instance, you can't (portably)
forward-declare STL containers such as std::vector since
implementations are permitted to attach as many extra template
parameters as they like, so long as they're given defaults.


Last I heard, that's wrong. See http://tinyurl.com/oestb.
Jonathan

May 2 '06 #6
Jonathan Mcdougall wrote:
mlimber wrote:
Noah Roberts wrote:
I like templates but getting rid of the compile time dependencies with
them can be tough...


Sometimes it's impossible. For instance, you can't (portably)
forward-declare STL containers such as std::vector since
implementations are permitted to attach as many extra template
parameters as they like, so long as they're given defaults.


Last I heard, that's wrong. See http://tinyurl.com/oestb.


I stand corrected!

Cheers! --M

May 2 '06 #7

"mlimber" <ml*****@gmail.com> skrev i meddelandet
news:11*********************@g10g2000cwb.googlegro ups.com...
Jonathan Mcdougall wrote:
mlimber wrote:
> Noah Roberts wrote:
> > I like templates but getting rid of the compile time
> > dependencies with
> > them can be tough...
>
> Sometimes it's impossible. For instance, you can't (portably)
> forward-declare STL containers such as std::vector since
> implementations are permitted to attach as many extra template
> parameters as they like, so long as they're given defaults.


Last I heard, that's wrong. See http://tinyurl.com/oestb.


I stand corrected!

Cheers! --M


The real reason you cannot forward declare std::vector is that it has
default template parameters. For some reason, the language doesn't let
you repeat the defaults in both a template definition and a
declaration. So, as long as the std::vector definition contains those
defaults, you cannot write a valid declaration for it.

Note that iosfwd solves this problem for iostreams, but not for any
other std::classes.
Bo Persson
May 2 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by mjm | last post: by
6 posts views Thread by Steven T. Hatton | last post: by
5 posts views Thread by John Gabriele | last post: by
11 posts views Thread by aleko | last post: by
9 posts views Thread by vishnu | last post: by
2 posts views Thread by Neo | last post: by
12 posts views Thread by fox | last post: by
2 posts views Thread by Carlos Martinez Garcia | last post: by
reply views Thread by Rune Allnor | last post: by
18 posts views Thread by didacticone | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.