| 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.
.
|
|
|
|
|
|

|
Related Articles |
|
|