[type_traits] MSVC rejects typename -- why?

Hello all, The following code compiles on GCC (v3.4.3) but it does not on MSVC (cl.exe v14): #include <boost/type_traits.hpp> template<typename T> void f(T& x) { struct s { T g() { // GCC needs this typename but MSVC does not -- why?? typename boost::remove_reference<T&>::type i = 0; return i; } }; x = s().g(); } int main() { int x; f(x); return 0; } MSVC does not accept the `typename` inside `s::g` because it says it's not within a template (but I think it is within a template...). GCC instead requires that `typename`. Which compiler is right? (What does the standard say?) How do I program this code so it works on all compilers? Thank you very much. -- Lorenzo

Message du 24/03/11 01:01 De : "Lorenzo Caminiti" A : boost@lists.boost.org Copie à : Objet : [boost] [type_traits] MSVC rejects typename -- why?
Hello all,
The following code compiles on GCC (v3.4.3) but it does not on MSVC (cl.exe v14):
#include
template void f(T& x) { struct s { T g() { // GCC needs this typename but MSVC does not -- why?? typename boost::remove_reference::type i = 0; return i; } }; x = s().g(); }
MSVC does not accept the `typename` inside `s::g` because it says it's not within a template (but I think it is within a template...). GCC instead requires that `typename`.
Which compiler is right? (What does the standard say?) How do I program this code so it works on all compilers?
here is a macro BOOST_TYPENAME in Boost.Config that was used for this purposes with old compilers. HTH, Vicente

Vicente Botet wrote:
> Message du 24/03/11 01:01 > De : "Lorenzo Caminiti" > A : boost@lists.boost.org > Copie à : > Objet : [boost] [type_traits] MSVC rejects typename -- why? > > Hello all, > > The following code compiles on GCC (v3.4.3) but it does not on MSVC > (cl.exe v14): > > #include > > template > void f(T& x) { > struct s { > T g() { > // GCC needs this typename but MSVC does not -- why?? > typename boost::remove_reference::type i = 0; > return i; > } > }; > x = s().g(); > } > > MSVC does not accept the `typename` inside `s::g` because it says it's > not within a template (but I think it is within a template...). GCC > instead requires that `typename`. > > Which compiler is right? (What does the standard say?) How do I > program this code so it works on all compilers?
here is a macro BOOST_TYPENAME in Boost.Config that was used for this purposes with old compilers.
I tried BOOST_DEDUCED_TYPENAME but it still does not work on my MSVC compiler... is this a problem with Boost.Config? #include <boost/type_traits.hpp> #include <boost/config.hpp> template void f(T& x) { struct s { T g() { BOOST_DEDUCED_TYPENAME boost::remove_reference<T&>::type i = 0; return i; } }; x = s().g(); } int main() { int x; f(x); return 0; } E:\sandbox\boost-sandbox-local\libs\local\example>cl /EHs /I..\..\.. /I"c:\Progr am Files\boost\boost_1_46_1" 02.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. 02.cpp 02.cpp(9) : error C2899: typename cannot be used outside a template declaration Thanks. --Lorenzo -- View this message in context: http://boost.2283326.n4.nabble.com/type-traits-MSVC-rejects-typename-why-tp3... Sent from the Boost - Dev mailing list archive at Nabble.com.

Hi, It seems the compiler is not seen it is inside an outer macro. In this case it seems that we need another macro e.g.BOOST_NESTED_TYPENAME. You could try to follow the protocol of adding a new macro andpropose apatch to John. An other alternative: I suspect that the nested structure is code that you generate with your macros in Boost.Local orBoost.Contract. I propose you to define a nested template template void f(T& x) { template struct s { T g() { typename boost::remove_reference::type i = 0; return i; } }; x = s().g(); } HTH, Vicente
participants (3)
-
lcaminiti
-
Lorenzo Caminiti
-
Vicente BOTET