Specialization of template functions

M

Markus Petermann

Hello,

I have a small problem I want to demonstrate with a small demo program:

-------------- Snip --------------

#include <string>

namespace
{
template< bool I >
struct StaticAssert
{
};

template<>
struct StaticAssert< true >
{
enum { value = 1 };
};

#define STATIC_ASSERT( V ) StaticAssert< V >::value

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}

-------------- Snip --------------

(The upper part is like the BOOST_STATIC_ASSERT.)

This can be compiled perfectly with the GCC 3.3 compiler, but not with
GCC 4.0 or 4.1. I want to keep this code because it causes a compiler
error when the template function is called and not one of the
specialized ones.

Has anybody an idea?
 
J

Jakob Bieling

Markus Petermann said:
#include <string>

namespace
{
template< bool I >
struct StaticAssert
{
};

template<>
struct StaticAssert< true >
{
enum { value = 1 };
};

#define STATIC_ASSERT( V ) StaticAssert< V >::value

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
}

template<>
std::string dump( const std::string& value )

Don't you need to write

template <>
std::string dump <std::string> ( const std::string& value )

?
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}
This can be compiled perfectly with the GCC 3.3 compiler, but not with
GCC 4.0 or 4.1.

What is the error message?

hth
 
K

Kai-Uwe Bux

Markus said:
Hello,

I have a small problem I want to demonstrate with a small demo program:

-------------- Snip --------------

#include <string>

namespace
{
template< bool I >
struct StaticAssert
{
};

template<>
struct StaticAssert< true >
{
enum { value = 1 };
};

#define STATIC_ASSERT( V ) StaticAssert< V >::value

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}

-------------- Snip --------------

(The upper part is like the BOOST_STATIC_ASSERT.)

This can be compiled perfectly with the GCC 3.3 compiler, but not with
GCC 4.0 or 4.1. I want to keep this code because it causes a compiler
error when the template function is called and not one of the
specialized ones.

Has anybody an idea?


What about:

#include <string>

namespace
{
template< bool I >
struct StaticAssert;

template<>
struct StaticAssert< true >
{};

#define STATIC_ASSERT( X ) StaticAssert< X >();

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
return ( value );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}
 
M

Markus Petermann

Hello,

Jakob said:
What is the error message?

Sorry, I forgot. The error message is:

g++ alpha.cpp -o alpha
alpha.cpp: In function 'std::string<unnamed>::dump(const T&)':
alpha.cpp:21: error: 'value' is not a member of
'<unnamed>::StaticAssert<false>'

(Line 21 is the one with the STATIC_ASSERT( false ) macro.)

IMHO the compiler tries to compile the template method, although I call
the specialized one for strings.
 
M

Markus Petermann

Hello,

Kai-Uwe Bux said:
What about:
<Snip>

Great! This code can be compiled with G++ 4.0 and 4.1.

One minor problem: Your fix is in the part that is normally provided by
the boost library (the BOOST_STATIC_ASSERT macro, to be exactly). I am
going to search the boost bug reports if there were similar problems.

But with this information I can build my own static assert as a
temporary fix.

Thank you!
 
P

Pierre Barbier de Reuille

Kai-Uwe Bux said:
Markus Petermann wrote:
[...]

What about:

#include <string>

namespace
{
template< bool I >
struct StaticAssert;

template<>
struct StaticAssert< true >
{};

#define STATIC_ASSERT( X ) StaticAssert< X >();

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
return ( value );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}

But what is the use of STATIC_ASSERT in your example ?
If I change the main into :

int main()
{
const int i = 3;
dump(i);
return 0;
}

The error I get is :

spec.cc: In function 'std::string<unnamed>::dump(const T&) [with T = int]':
spec.cc:32: instantiated from here
spec.cc:19: error: invalid conversion from 'const int' to 'const char*'
spec.cc:19: error: initializing argument 1 of
'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*,
const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>,
_Alloc = std::allocator<char>]'
make: *** [spec] Erreur 1

Thus there is no error on the STATIC_ASSERT line ...(line 19 is for me
the line of the return statement after the STATIC_ASSERT).

Pierre
 
K

Kai-Uwe Bux

Pierre said:
Kai-Uwe Bux said:
Markus Petermann wrote:
[...]

What about:

#include <string>

namespace
{
template< bool I >
struct StaticAssert;

template<>
struct StaticAssert< true >
{};

#define STATIC_ASSERT( X ) StaticAssert< X >();

template< typename T >
std::string dump( const T& value )
{
STATIC_ASSERT( false );
return ( value );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
const std::string text = "Hello World!";
dump( text );

return 0;
}

But what is the use of STATIC_ASSERT in your example ?
If I change the main into :

int main()
{
const int i = 3;
dump(i);
return 0;
}

The error I get is :

spec.cc: In function 'std::string<unnamed>::dump(const T&) [with T =
int]':
spec.cc:32: instantiated from here
spec.cc:19: error: invalid conversion from 'const int' to 'const char*'
spec.cc:19: error: initializing argument 1 of
'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*,
const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>,
_Alloc = std::allocator<char>]'
make: *** [spec] Erreur 1

Thus there is no error on the STATIC_ASSERT line ...(line 19 is for me
the line of the return statement after the STATIC_ASSERT).

I get two error messages:

news_group> cc++ xxx.cc
xxx.cc: In function 'std::string<unnamed>::dump(const T&) [with T = int]':
xxx.cc:32: instantiated from here
xxx.cc:17: error: invalid use of undefined
type 'struct<unnamed>::StaticAssert<false>'
xxx.cc:6: error: declaration of 'struct<unnamed>::StaticAssert<false>'
xxx.cc:18: error: conversion from 'const int' to non-scalar
' requested


As you can see, the first corresponds to the STATIC_ASSERT.

Try compiling this:

#include <string>

namespace
{
template< bool I >
struct StaticAssert;

template<>
struct StaticAssert< true >
{};

#define STATIC_ASSERT( X ) StaticAssert< X >();

template< typename T >
T dump( const T& value )
{
STATIC_ASSERT( false );
return ( value );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
int const i = 3;
dump( i );
return 0;
}

I think, it should give you one and only one error, and that error should
relate to STATIC_ASSERT.


Best

Kai-Uwe Bux
 
P

Pierre Barbier de Reuille

Kai-Uwe Bux said:
Pierre Barbier de Reuille wrote: [...]

Try compiling this:

#include <string>

namespace
{
template< bool I >
struct StaticAssert;

template<>
struct StaticAssert< true >
{};

#define STATIC_ASSERT( X ) StaticAssert< X >();

template< typename T >
T dump( const T& value )
{
STATIC_ASSERT( false );
return ( value );
}

template<>
std::string dump( const std::string& value )
{
return value;
}
}

int main( const int argc,
char* argv[] )
{
int const i = 3;
dump( i );
return 0;
}

I think, it should give you one and only one error, and that error should
relate to STATIC_ASSERT.

Indeed, I forgot to remove completely the body of the main template
declaration of StaticAssert :/

Thanks,

Pierre
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top