By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,804 Members | 1,631 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,804 IT Pros & Developers. It's quick & easy.

why can I test for is_volatile<T> but I can't test for is_unsigned<T>?

P: n/a
Why do I get a syntax error below?

I don't see why volatile works but unsigned does not work.

I'm not looking for an answer of the form, "Because the Standard says
so", or "Because the C++ grammer says so"; I'm looking for an
explanation of *why* the Standard and/or the grammar say so.

Thanks,

Robert Schwartz


#include <iostream>

template <typename T>
class is_volatile/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_volatile<volatile T>
{ public: static const bool value = true; };

template <typename T>
void test1(void)
{
std::cout << is_volatile<T>::value << std::endl;
}

template <typename T>
class is_unsigned/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_unsigned<unsigned T> // "syntax error before '>' token" on
this line.
{ public: static const bool value = true; };

template <typename T>
void test2(void)
{
std::cout << is_unsigned<T>::value << std::endl;
}

int main(void)
{
test1<volatile int>();

test2<unsigned int>();

return 0;
}
Jul 22 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Robert Allan Schwartz wrote:
Why do I get a syntax error below?

I don't see why volatile works but unsigned does not work.

I'm not looking for an answer of the form, "Because the Standard says
so", or "Because the C++ grammer says so"; I'm looking for an
explanation of *why* the Standard and/or the grammar say so.
IANALG but I think that unsigned is part of the type itself rather than
a qualifier.
Since there are only three (maybe four) unsigned types, why not do the
below:

#include <iostream>

template <typename T>
class is_volatile/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_volatile<volatile T>
{ public: static const bool value = true; };

template <typename T>
void test1(void)
{
std::cout << is_volatile<T>::value << std::endl;
}

template <typename T>
class is_unsigned/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_unsigned<unsigned T> // "syntax error before '>' token" on
this line.
{ public: static const bool value = true; };

template <>
class is_unsigned<unsigned char>
{ public: static const bool value = true; };

#ifdef UNSIGNED_INT_IS_A_DISTINCT_TYPE_
template <>
class is_unsigned<unsigned int> // not sure if this is needed
this line.
{ public: static const bool value = true; };
#endif

template <>
class is_unsigned<unsigned short>
this line.
{ public: static const bool value = true; };

template <>
class is_unsigned<unsigned long>
this line.
{ public: static const bool value = true; };

#ifdef UNSIGNED_LONG_LONG_IS_DEFINED_BY_THE_COMPILER_
template <>
class is_unsigned<unsigned long long>
this line.
{ public: static const bool value = true; };
#endif
template <typename T>
void test2(void)
{
std::cout << is_unsigned<T>::value << std::endl;
}

int main(void)
{
test1<volatile int>();

test2<unsigned int>();

return 0;
}

Jul 22 '05 #2

P: n/a
On Wed, 11 Aug 2004 11:12:56 -0700, Robert Allan Schwartz wrote:
I don't see why volatile works but unsigned does not work.
As noted by other(s), volatile (like const) is a type
qualifier. 'unsigned' is a part of the type.
template <typename T>
class is_unsigned/*<T>*/
{ public: static const bool value = false; };


You can implement is_unsigned in terms of std::numeric_limits:

#include <iostream>
#include <limits>

int main(void)
{
std::cout << std::numeric_limits<int>::is_signed << '\n';
}

Ali
Jul 22 '05 #3

P: n/a
I understand that there is another way to implement is_unsigned<T>.
I understand that 'volatile' is a qualifier and 'unsigned' is part of
the type.
What I want to know is, why can I ask type questions of the form
'is_[qualifier]<T>', but I cannot ask type questions of the form
'is_[part_of_type]<T>'?
Did the Standards Committee decide to allow the former and disallow
the latter?
Is this simply an artifact of the grammar?
I'm looking for a deeper explanation.
Anyone got one?

Thanks,

Robert

red floyd <no*****@here.dude> wrote in message news:<8u*****************@newssvr21.news.prodigy.c om>...
Robert Allan Schwartz wrote:
Why do I get a syntax error below?

I don't see why volatile works but unsigned does not work.

I'm not looking for an answer of the form, "Because the Standard says
so", or "Because the C++ grammer says so"; I'm looking for an
explanation of *why* the Standard and/or the grammar say so.

IANALG but I think that unsigned is part of the type itself rather than
a qualifier.
Since there are only three (maybe four) unsigned types, why not do the
below:

#include <iostream>

template <typename T>
class is_volatile/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_volatile<volatile T>
{ public: static const bool value = true; };

template <typename T>
void test1(void)
{
std::cout << is_volatile<T>::value << std::endl;
}

template <typename T>
class is_unsigned/*<T>*/
{ public: static const bool value = false; };

template <typename T>
class is_unsigned<unsigned T> // "syntax error before '>' token" on
this line.
{ public: static const bool value = true; };

template <>
class is_unsigned<unsigned char>
{ public: static const bool value = true; };

#ifdef UNSIGNED_INT_IS_A_DISTINCT_TYPE_
template <>
class is_unsigned<unsigned int> // not sure if this is needed
this line.
{ public: static const bool value = true; };
#endif

template <>
class is_unsigned<unsigned short>
this line.
{ public: static const bool value = true; };

template <>
class is_unsigned<unsigned long>
this line.
{ public: static const bool value = true; };

#ifdef UNSIGNED_LONG_LONG_IS_DEFINED_BY_THE_COMPILER_
template <>
class is_unsigned<unsigned long long>
this line.
{ public: static const bool value = true; };
#endif
>
template <typename T>
void test2(void)
{
std::cout << is_unsigned<T>::value << std::endl;
}

int main(void)
{
test1<volatile int>();

test2<unsigned int>();

return 0;
}

Jul 22 '05 #4

P: n/a

"Robert Allan Schwartz" <no****@tessellation.com> wrote in message
news:11**************************@posting.google.c om...
I understand that there is another way to implement is_unsigned<T>.
I understand that 'volatile' is a qualifier and 'unsigned' is part of the type.
What I want to know is, why can I ask type questions of the form
'is_[qualifier]<T>', but I cannot ask type questions of the form
'is_[part_of_type]<T>'?
You can ask both types of questions, as the responses to your post
have shown.
Did the Standards Committee decide to allow the former and disallow
the latter?
Is this simply an artifact of the grammar?
I'm looking for a deeper explanation.


What we need is a deeper explanation of you question.

Jonathan
Jul 22 '05 #5

P: n/a
Robert Allan Schwartz wrote:
I understand that there is another way to implement is_unsigned<T>.
I understand that 'volatile' is a qualifier and 'unsigned' is part of
the type.
What I want to know is, why can I ask type questions of the form
'is_[qualifier]<T>', but I cannot ask type questions of the form
'is_[part_of_type]<T>'?
Did the Standards Committee decide to allow the former and disallow
the latter?
Is this simply an artifact of the grammar?
I'm looking for a deeper explanation.
Anyone got one?


It is the grammar. You should consider it an accident that the typename
"unisgned int" consists of two words. After lexical analysis in the
compiler, very likely, this name becomes just one token. This is, when
the compiler deals with all the template magic, the information you want
is lost already.

What you are trying to do is like writing a template that tests whether a
typename starts with the letter "i".

However, since "unsigned" is not a qualifier, there are no user-defined
types that are unsigned or signed. Thus your template is meaningfull only
for a small number of basic types. For these you can provide specializations
and that way build is_unsigned<T> so that it checks true for the unsigned
basic types. But then, again, this has been done already in numeric_limits.
Best

Kai-Uwe
Jul 22 '05 #6

P: n/a
Let me try to refine my question.

In many cases, I can ask if a type is composed of two parts: a token
(e.g. * or &) or a keyword (e.g. const or volatile), followed by
another type.

I can ask if a type is "pointer to T".
I can ask if a type is "reference to T".
I can ask if a type is "const T".
I can ask if a type is "volatile T".
I cannot ask if a type is "unsigned T".
^^^

This appears to be an asymmetry.

Why is there an asymmetry?

I understand that there is another way to ask is_unsigned<T>. That
does not answer my question.
I understand that 'volatile' is a qualifier and 'unsigned' is not.
That does not answer my question.

Thanks,

Robert

"Jonathan Turkanis" <te******@kangaroologic.com> wrote in message news:<2o************@uni-berlin.de>...
"Robert Allan Schwartz" <no****@tessellation.com> wrote in message
news:11**************************@posting.google.c om...
I understand that there is another way to implement is_unsigned<T>.
I understand that 'volatile' is a qualifier and 'unsigned' is part

of
the type.
What I want to know is, why can I ask type questions of the form
'is_[qualifier]<T>', but I cannot ask type questions of the form
'is_[part_of_type]<T>'?


You can ask both types of questions, as the responses to your post
have shown.
Did the Standards Committee decide to allow the former and disallow
the latter?
Is this simply an artifact of the grammar?
I'm looking for a deeper explanation.


What we need is a deeper explanation of you question.

Jonathan

Jul 22 '05 #7

P: n/a
Robert Allan Schwartz wrote:
Let me try to refine my question.

In many cases, I can ask if a type is composed of two parts: a token
(e.g. * or &) or a keyword (e.g. const or volatile), followed by
another type.

I can ask if a type is "pointer to T".
I can ask if a type is "reference to T".
I can ask if a type is "const T".
I can ask if a type is "volatile T".
I cannot ask if a type is "unsigned T".
^^^

This appears to be an asymmetry.


You can view this as a crack in the *lexical* structure of C++.
"unsigned int" should rather be "unsigned_int" but for compatibility
reasons to C they kept it the other way. Now, since the thing is only
an entity of the lexical structure, you must understand, that for the
compiler "unsigned int" actually reads as "unsigned_int", the parser
might get an appropriate token from the lexical scanner..."unsigned T"
can't be understood, because the comprehension would need to happen at
a semantic level (where T is identified as a type) -- on a lexical
level it doesn't make sense and will never make it into the parser.

Okay, the ones in charge could have promoted "unsigned" out of the
lowland of lexical scanning to the semantic pastures (just to correct
the unpleasant visual artifact) but that would have made everything
much more complicated: every part that deals with cv-qualifiers would
be forced to care for the completely uninteresting, dull and usually
(except for a couple of primitive cases) inapplicable case of
"unsigned". An extra qualifier would burden the user as well. For
example, if you want to do something like "remove_qualifier" you'll
have to check 4 different combinations of qualifiers, adding unsigned
would make you have 8 cases to check!! Qualifiers multiply the number
of possible qualifiers Types, so it's better to keep only the useful
ones. Read this as: We really don't need "unsigned T", thus we don't
commit anybody to parse it.

Marco

Jul 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.