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. | | | | re: Forward declarations, templates, and typedefs
Noah Roberts wrote:[color=blue]
> 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.[/color]
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 | | | | re: Forward declarations, templates, and typedefs
Noah Roberts wrote:[color=blue]
> 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.[/color]
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 | | | | re: Forward declarations, templates, and typedefs
mlimber wrote:
[color=blue][color=green]
> > 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.[/color]
>
> 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; }
> };[/color]
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... | | | | re: Forward declarations, templates, and typedefs
Noah Roberts wrote:[color=blue]
> mlimber wrote:
>[color=green][color=darkred]
> > > 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.[/color]
> >
> > 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; }
> > };[/color]
>
> 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.[/color]
If the forward declaration and typedefs are used widely, then sure.
[color=blue]
> I like templates but getting rid of the compile time dependencies with
> them can be tough...[/color]
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 | | | | re: Forward declarations, templates, and typedefs
mlimber wrote:[color=blue]
> Noah Roberts wrote:[color=green]
> > I like templates but getting rid of the compile time dependencies with
> > them can be tough...[/color]
>
> 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.[/color]
Last I heard, that's wrong. See http://tinyurl.com/oestb.
Jonathan | | | | re: Forward declarations, templates, and typedefs
Jonathan Mcdougall wrote:[color=blue]
> mlimber wrote:[color=green]
> > Noah Roberts wrote:[color=darkred]
> > > I like templates but getting rid of the compile time dependencies with
> > > them can be tough...[/color]
> >
> > 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.[/color]
>
> Last I heard, that's wrong. See http://tinyurl.com/oestb.[/color]
I stand corrected!
Cheers! --M | | | | re: Forward declarations, templates, and typedefs
"mlimber" <mlimber@gmail.com> skrev i meddelandet
news:1146599753.550599.77760@g10g2000cwb.googlegro ups.com...[color=blue]
> Jonathan Mcdougall wrote:[color=green]
>> mlimber wrote:[color=darkred]
>> > 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.[/color]
>>
>> Last I heard, that's wrong. See http://tinyurl.com/oestb.[/color]
>
> I stand corrected!
>
> Cheers! --M
>[/color]
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 |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,471 network members.
|