template typename parameter cannot be "void"?

  • Thread starter Sylvain Guilley
  • Start date
S

Sylvain Guilley

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
}
 
P

peter koch

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
 
S

Sylvain Guilley

peter said:
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.
 
T

tragomaskhalos

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:

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.
 

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,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top