template typename parameter cannot be "void"?



 DEVELOP > c-Plus-Plus > template typename parameter cannot be "void"?

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "Sylvain Guilley"
Date: 03 Feb 2008 07:35:02 AM
Object: template typename parameter cannot be "void"?
Hello,
I am wondering why "typename D" can be anything, a class or a
primitive type (int, float, etc.) but not void?
Now, in some situations, it would make sense to specialize a template
typename into "void".
I provide an example below. Actually, I am fetching an idiomatic way
to design a generic singleton factory that is able to create a single
instance of a class (C) either with or without initialization parameters
(D). My first idea fails (see line marked with comment "// KO").
Any suggestions?
Thanks, Sylvain GUILLEY.
template <class C, typename D> class singleton
{
static int nb_references;
static C* pinstance;
public:
static C* new_instance( D );
static void delete_instance();
};
// Initialize the reference count to zero
template <class C, typename D> int singleton<C,D>::nb_references = 0;
// Initialize pointer
template <class C, typename D> C* singleton<C,D>::pinstance = 0;
// Proxy to return the instance
template <class C, typename D> C* singleton<C,D>::new_instance( D init )
{
if( nb_references++ == 0 ) pinstance = new C( init );
return pinstance; // Address of sole instance
}
// Proxy to delete the instance
template <class C, typename D> void singleton<C,D>::delete_instance()
{
if( --nb_references == 0 ) delete pinstance;
}
// Class from which we would like to be able to call either ctor
struct a
{
a( int ) {}
a( void ) {}
};
int main()
{
a* Aint = singleton<a, int >::new_instance( 0 ); // OK
a* Avoid = singleton<a, void>::new_instance( void ); // KO
}
.

User: "peter koch"

Title: Re: template typename parameter cannot be "void"? 03 Feb 2008 07:50:07 AM
On 3 Feb., 14:35, Sylvain Guilley <sylvain.guil...@free.fr> wrote:

Hello,

=A0 I am wondering why "typename D" can be anything, a class or a
primitive type (int, float, etc.) but not void?

But you can - no problem with that.
The problem with your example is that you can't create a variable of
type void, so you have to find an alternative solution (e.g.
specialise for void).
/Peter
.
User: "Sylvain Guilley"

Title: Re: template typename parameter cannot be "void"? 03 Feb 2008 12:08:34 PM
peter koch wrote:

On 3 Feb., 14:35, Sylvain Guilley <sylvain.guil...@free.fr> wrote:

Hello,

I am wondering why "typename D" can be anything, a class or a
primitive type (int, float, etc.) but not void?

But you can - no problem with that.

The problem with your example is that you can't create a variable of
type void, so you have to find an alternative solution (e.g.
specialise for void).

/Peter

Right, a variable cannot be of type void.
However, my problem is that the following two non-template function
definitions are legal:
void foo( int ) { return; }
void foo( void ) { return; }
but it seems impossible to unify the parameter of foo (either int or
void) into a template typename. For instance, in this code snippet:
template <typename T> struct A
{
void foo( T ); /* line 3 */
};
template<> void A<int> ::foo( int ) {} // (1) OK
template<> void A<void>::foo( void ) {} // (2) KO /* line 7 */
g++ 4.1.2 20061115 complains that:
debug.cpp: In instantiation of 'A<void>':
debug.cpp:7: instantiated from here
debug.cpp:3: error: invalid parameter type 'void'
debug.cpp:3: error: in declaration 'void A<T>::foo(T)'
debug.cpp:7: error: no member function 'foo' declared in 'A<void>'
debug.cpp:7: error: invalid function declaration
One workaround consists in defining a sibling class B, "specialized" for
T=void:
struct B
{
void foo( void ) {} // (3) OK ... alternative for broken (2)
};
Is this workaround the only one?
Regards, Sylvain.
.
User: "tragomaskhalos"

Title: Re: template typename parameter cannot be "void"? 03 Feb 2008 05:27:26 PM
On 3 Feb, 18:08, Sylvain Guilley <sylvain.guil...@free.fr> wrote:

peter koch wrote:

On 3 Feb., 14:35, Sylvain Guilley <sylvain.guil...@free.fr> wrote:

Hello,


=A0 I am wondering why "typename D" can be anything, a class or a
primitive type (int, float, etc.) but not void?


But you can - no problem with that.


The problem with your example is that you can't create a variable of
type void, so you have to find an alternative solution (e.g.
specialise for void).


/Peter


Right, a variable cannot be of type void.

However, my problem is that the following two non-template function
definitions are legal:

void foo( int =A0) { return; }
void foo( void ) { return; }

but it seems impossible to unify the parameter of foo (either int or
void) into a template typename. For instance, in this code snippet:

Peter's explanation was actually complete -
your confusion stems from the mismatch between semantics and
syntax in this case. Don't think of void foo (void);
as "taking a void parameter", because this is of course
misleading - it's just another way of spelling
void foo (); (as I'm sure you know), provided for
historical reasons of C compatibility. When viewed in
these terms the behaviour of the language is seen to
be sensible and logically correct.
.




  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER