
The coding guidelines document (boost/more/int_const_guidelines.htm), states the following... Always use a fully qualified name to refer to an integral constant expression. For example: typedef myclass< ::boost::is_integral<some_type>::value> mytypedef; Rationale: at least one compiler (Borland's), doesn't recognise the name of a constant as an integral constant expression unless the name is fully qualified (which is to say it starts with ::). However, it appears that the same compiler (BCB6) has problems if the '::' is left in. For example... template <class T> struct Foo { typedef typename ::boost::remove_reference< T >::type type; typedef typename ::boost::add_reference< typename ::boost::add_const< type >::type >::type ref_to_const_type; }; fails to compile. Initially I thought it had something to do with typename (e.g., another BOOST_DEDUCED_TYPENAME) because, the first, simpler line compiles if I remove the "typename" keyword. Unfortunately, the following does not compile either template <class T> struct Foo { typedef ::boost::remove_reference< T >::type type; typedef ::boost::add_reference< ::boost::add_const< type >::type >::type ref_to_const_type; }; After seeing a notice on this list a few minutes ago, I decided to remove the '::' and whaddya know... template <class T> struct Foo { typedef typename boost::remove_reference< T >::type type; typedef typename boost::add_reference< typename boost::add_const< type >::type >::type ref_to_const_type; }; this compiles correctly. So, I am left scratching my head, wondering what to do if I want to use TypeTraits in a portbale manner. Thanks!

I hate replying to my own post, but I forgot to add... Yes, I know that I am using a type, not an integral constant value, and I should have come up with an example in that vein. However, all the examples and docs use the fully qualified version for both types and values...

Thanks for all the input. I posted a "modification" shortly after the original, noting that I was using types not integral constants, but I guess it did not make it out. However, after reading the replies, the point I made in the "modification" seems to stand. All the documentation uses fully qualified names even when referring to types, which is misleading, and that is what I was trying to get at (though not very well). The rationale for doing so only mentions integral constants, but just about all the references in the documentation use fully qualified names for types as well. To me, the documentation is encouraging fully qualified names for everything. Maybe the documentation should change? Maybe something should be added to say that the '::' is needed for integral constants only and using them for types is dangerous? Maybe I am the only one with this problem and I should just quietly go away ;-> In any event, I am very appreciative for the input, even though you thought I could not tell the difference between a type and integral constant...

Thanks for all the input. I posted a "modification" shortly after the original, noting that I was using types not integral constants, but I guess it did not make it out.
Yes, I saw that right after I posted my reply...
However, after reading the replies, the point I made in the "modification" seems to stand. All the documentation uses fully qualified names even when referring to types, which is misleading, and that is what I was trying to get at (though not very well). The rationale for doing so only mentions integral constants, but just about all the references in the documentation use fully qualified names for types as well. To me, the documentation is encouraging fully qualified names for everything.
Are you sure? I just searched the type traits docs and the integral-constant-expression white paper for " ::", and only found one occurance where a type was refered to with a leading ::. Even so, it's easy to be tripped up by this, and with luck I'm going to rewrite the type traits docs "real soon now", so I'll try and make this clearer.
Maybe the documentation should change? Maybe something should be added to say that the '::' is needed for integral constants only and using them for types is dangerous? Maybe I am the only one with this problem and I should just quietly go away ;->
Nope, feedback is always useful, John.

On Fri, 11 Mar 2005 17:09:11 -0000 "John Maddock" <john@johnmaddock.co.uk> wrote:
Are you sure? I just searched the type traits docs and the integral-constant-expression white paper for " ::", and only found one
occurance where a type was refered to with a leading ::.
The most clear example is on the main page, boost/libs/type_traits/index.html, about half way down starting with the section, "Transformations Between Types." Pretty much everything there that summarizes the features has the leading '::' in the "Expression" examples. Maybe the intent is simply to say that they are in ::boost, but I do not recall seeing this kind of specification in other boost docs, and mized with the coding standards it confused me (but obviously that is not a difficult task).
Even so, it's easy to be tripped up by this, and with luck I'm going to rewrite the type traits docs "real soon now", so I'll try and make this clearer.
Cool. BTW, how would you state the differences between using type_traits and mpl, as Dave suggested in this thread?

The most clear example is on the main page, boost/libs/type_traits/index.html, about half way down starting with the section, "Transformations Between Types." Pretty much everything there that summarizes the features has the leading '::' in the "Expression" examples.
Oh, shucks, missed those.
Maybe the intent is simply to say that they are in ::boost, but I do not recall seeing this kind of specification in other boost docs, and mized with the coding standards it confused me (but obviously that is not a difficult task).
Even so, it's easy to be tripped up by this, and with luck I'm going to rewrite the type traits docs "real soon now", so I'll try and make this clearer.
Cool. BTW, how would you state the differences between using type_traits and mpl, as Dave suggested in this thread?
They're not really in competition, think of mpl as a good way to combine and use type traits to do interesting things. John.

Jody Hagins wrote:
The coding guidelines document (boost/more/int_const_guidelines.htm), states the following...
Always use a fully qualified name to refer to an integral constant expression.
For example:
typedef myclass< ::boost::is_integral<some_type>::value> mytypedef;
Rationale: at least one compiler (Borland's), doesn't recognise the name of a constant as an integral constant expression unless the name is fully qualified (which is to say it starts with ::).
However, it appears that the same compiler (BCB6) has problems if the '::' is left in. For example...
template <class T> struct Foo { typedef typename ::boost::remove_reference< T >::type type; typedef typename ::boost::add_reference< typename ::boost::add_const< type >::type >::type ref_to_const_type; };
fails to compile.
This example doesn't contain any integral constant expressions, though.

"Peter Dimov" <pdimov@mmltd.net> writes:
This example doesn't contain any integral constant expressions, though.
And if you need a clean and foolproof way to do integral constant expressions portably, your best bet might be to use MPL's type wrappers and associated metafunctions. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Jody Hagins wrote:
The coding guidelines document (boost/more/int_const_guidelines.htm), states the following...
Always use a fully qualified name to refer to an integral constant expression.
For example:
typedef myclass< ::boost::is_integral<some_type>::value> mytypedef;
Rationale: at least one compiler (Borland's), doesn't recognise the name of a constant as an integral constant expression unless the name is fully qualified (which is to say it starts with ::).
However, it appears that the same compiler (BCB6) has problems if the '::' is left in. For example...
template <class T> struct Foo { typedef typename ::boost::remove_reference< T >::type type; typedef typename ::boost::add_reference< typename ::boost::add_const< type >::type >::type ref_to_const_type; };
fails to compile. Initially I thought it had something to do with typename (e.g., another BOOST_DEDUCED_TYPENAME) because, the first, simpler line compiles if I remove the "typename" keyword. Unfortunately, the following does not compile either
Well, this is neither a deduced context nor does it involve ICEs. Besides, as you might know, BCB has problem detecting dependent types and thus removing typename is always a good idea before suspecting other evil. There is really no point in always fully qualifying every name you use. Only do so when referring to a static member constant! In fact, the easiest way is to avoid non-type template arguments whenever possible and pass around types instead (see MPL Integral Constant Concept). When the compiler substitutes a template type paramter with its argument it is "fully qualified automatically": template<typename IC> struct X { // using IC::value is fine, here } This technique could make some Type Traits code more readable, I guess. Further, some passages might be overly careful..
So, I am left scratching my head, wondering what to do if I want to use TypeTraits in a portbale manner.
Fully qualify only when referring to static member constants. Regards, Tobias

Always use a fully qualified name to refer to an integral constant expression.
Correct, but see below.
However, it appears that the same compiler (BCB6) has problems if the '::' is left in. For example...
template <class T> struct Foo { typedef typename ::boost::remove_reference< T >::type type; typedef typename ::boost::add_reference< typename ::boost::add_const< type >::type >::type ref_to_const_type; };
fails to compile. Initially I thought it had something to do with typename (e.g., another BOOST_DEDUCED_TYPENAME) because, the first, simpler line compiles if I remove the "typename" keyword.
The thing is your typedef names a *type*, and *not* an integral constant expression, and as you have discovered, typename can't be followed by :: when using Borland. Keep the typename and remove the :: when using types, but keep in in when refering to values. Simple eh? (Just kidding). John.
participants (5)
-
David Abrahams
-
Jody Hagins
-
John Maddock
-
Peter Dimov
-
Tobias Schwinger