Martin Sebor wrote: >Travis Vitek wrote: >> >>
[...] > >I can think of a couple of options that satisfy these. I'm not sure >how palatable I find them yet, but I might get over their (initial) >lack of appeal if the payoff is worth it. YMMV. > >One is to drop the cv specializations of the __rw_is_xxx traits and >define the standard traits in terms of both remove_cv and the __rw >traits, like so: > > template <class _TypeT> > struct is_void: > integral_constant<bool, > _RW::__rw_is_void<typename > _RW::__rw_remove_cv<_TypeT>::type>::value> > { }; > >or more concisely: > > template <class _TypeT> > struct is_void: > integral_constant<bool, _RWSTD_IS_VOID (_TypeT)::value> > { }; > >with _RWSTD_IS_VOID() being #defined like so: > > #define _RWSTD_IS_VOID(T) \ > _RW::__rw_is_void<typename _RW::__rw_remove_cv<T>::type> > >All internal code would always need to use _RWSTD_IS_VOID() and >never _RW::__rw_is_void directly. > I think there is a problem with _RWSTD_IS_VOID() being defined like this because it can't be used outside a template (because of the typename keyword being used in the macro definition). $ cat u.cpp && g++ u.cpp namespace __rw { template <class T> struct __rw_remove_cv { typedef T type; }; template <class T> struct __rw_is_void { enum { value = 0 }; }; template <> struct __rw_is_void<void> { enum { value = 1 }; }; } #define _RW __rw #define _RWSTD_IS_VOID(T) \ _RW::__rw_is_void<typename _RW::__rw_remove_cv<T>::type> int main () { const bool b = _RWSTD_IS_VOID(void)::value; return b == 0; } u.cpp: In function 'int main()': u.cpp:23: error: using 'typename' outside of template Travis >