enable_if for class templates
Has anyone succeeded in specializing class templates with enable_if under VC++7.1? I have created the simplest example possible and cannot imagine how I could rewrite so that no Internal Compiler Error occurs. I have tried with both the boost 1.31 and 1.32 headers, with no difference. ------------------------------------------------------ #include <iostream> #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp> using namespace std; using namespace boost; template<typename T, typename E = void> struct A { enum { X = 0 }; }; template<typename T> struct A<T, typename enable_if< typename is_arithmetic<T> >::type> { enum { X = 1 }; }; template<typename T> struct A<T, typename enable_if< typename is_object<T> >::type> { enum { X = 2 }; }; struct B {}; int _tmain(int argc, _TCHAR* argv[]) { // cout << is_arithmetic<double>::value << endl; typedef A<float> Afloat; cout << Afloat::X << endl; // Internal Compiler Error cout << A<int>::X << endl; cout << A<B>::X << endl; return 0; } ------------------------------------------------------
I don't have access to VC++ 7.1 right now, so I can't find the whole problem you're having, but I have one comment: the uses of typename before is_arithmetic and is_object are unnecessary, since the types you're accessing are not members. I don't know if it will solve your ICE problem, but try removing those uses of typename. Otherwise, try using enable_if_c and adding ::value after the conditions (but still without a typename inside the condition for enable_if_c). Jeremiah Willcock On Sat, 18 Dec 2004, Agoston Bejo wrote:
Has anyone succeeded in specializing class templates with enable_if under VC++7.1? I have created the simplest example possible and cannot imagine how I could rewrite so that no Internal Compiler Error occurs. I have tried with both the boost 1.31 and 1.32 headers, with no difference.
------------------------------------------------------
#include <iostream> #include <boost/utility/enable_if.hpp> #include <boost/type_traits.hpp>
using namespace std; using namespace boost;
template<typename T, typename E = void> struct A { enum { X = 0 }; };
template<typename T> struct A<T, typename enable_if< typename is_arithmetic<T> >::type> { enum { X = 1 }; };
template<typename T> struct A<T, typename enable_if< typename is_object<T> >::type> { enum { X = 2 }; };
struct B {};
int _tmain(int argc, _TCHAR* argv[]) { // cout << is_arithmetic<double>::value << endl; typedef A<float> Afloat; cout << Afloat::X << endl; // Internal Compiler Error cout << A<int>::X << endl; cout << A<B>::X << endl; return 0; }
------------------------------------------------------
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
"Jeremiah Willcock" <jewillco@osl.iu.edu> wrote in message news:Pine.GSO.4.58.0412180004560.19449@earth.osl.iu.edu...
I don't have access to VC++ 7.1 right now, so I can't find the whole problem you're having, but I have one comment: the uses of typename before is_arithmetic and is_object are unnecessary, since the types you're accessing are not members. I don't know if it will solve your ICE problem, but try removing those uses of typename. Otherwise, try using enable_if_c and adding ::value after the conditions (but still without a typename inside the condition for enable_if_c).
Thanks a lot, it did solve the problem. Agoston
Agoston Bejo wrote:
Has anyone succeeded in specializing class templates with enable_if under VC++7.1?
Yes, I do it once in a while. I'd do it more if I didn't have to support old compilers.
I have created the simplest example possible and cannot imagine how I could rewrite so that no Internal Compiler Error occurs.
Obviously the ICE is a microsoft bug. It occurs in VC8.0 beta, too, so it should be reported. However, the real problem is that int and float both satisfy is_object and is_arithmetic, so two partial specializations match equally well. Here's the output from como 4.3.3: "C:\DOCUME~1\turkanis\Home\C++\overloadvc71\example.cpp", line 31: error: more than one partial specialization matches the template argument list of class "A<float, void>" "A<T, boost::enable_if<boost::is_arithmetic<T>, void>::type>" "A<T, boost::enable_if<boost::is_object<T>, void>::type>" cout << Afloat::X << endl; // Internal Compiler Error ^ "C:\DOCUME~1\turkanis\Home\C++\overloadvc71\example.cpp", line 32: error: more than one partial specialization matches the template argument list of class "A<int, void>" "A<T, boost::enable_if<boost::is_arithmetic<T>, void>::type>" "A<T, boost::enable_if<boost::is_object<T>, void>::type>" cout << A<int>::X << endl; Jonathan
Here's a stripped-down version of the program (with no includes) which reproduces the ICE. Jonathan ------------- template<bool Condition> struct enable_if { typedef void type; }; template<> struct enable_if<false> { }; template<typename T> struct alway_true { enum { value = 1 }; }; template<typename T, typename E = void> struct A; template<typename T> struct A<T, typename enable_if< alway_true<T>::value >::type> { }; template<typename T> struct A<T, typename enable_if< alway_true<T>::value >::type> { }; // Instantiate A: A<int> a;
participants (3)
-
Agoston Bejo
-
Jeremiah Willcock
-
Jonathan Turkanis