[mpl, enable_if] "Failed to specialize function template"

Hello, The following code fails to compile (MSVC10, Boost 1.45) with "error C2893: Failed to specialize function template..." It seems that the compiler tries to evaluate mpl::apply, doesn't it? #include <boost/mpl/apply.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/or.hpp> #include <boost/mpl/and.hpp> #include <boost/mpl/always.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/utility/enable_if.hpp> using namespace boost::mpl; using boost::is_same; template<typename Type> void test(Type, typename boost::enable_if < and_ < not_<boost::is_same<Type, int> >, apply<always<true_>, typename Type::my_type> >
::type* dummy = 0) { }
template<typename Type> void test(Type, typename boost::disable_if < and_ < not_<boost::is_same<Type, int> >, apply<always<true_>, typename Type::my_type> >
::type* dummy = 0) { }
int main(int argc, char* argv[]) { test(int()); return 0; }

2010/12/14 Igor R <boost.lists@gmail.com>
Hello,
The following code fails to compile (MSVC10, Boost 1.45) with "error C2893: Failed to specialize function template..." It seems that the compiler tries to evaluate mpl::apply, doesn't it?
#include <boost/mpl/apply.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/or.hpp> #include <boost/mpl/and.hpp> #include <boost/mpl/always.hpp> #include <boost/type_traits/is_same.hpp> #include <boost/utility/enable_if.hpp>
using namespace boost::mpl; using boost::is_same;
template<typename Type> void test(Type, typename boost::enable_if < and_ < not_<boost::is_same<Type, int> >, apply<always<true_>, typename Type::my_type>
::type* dummy = 0)
{ }
template<typename Type> void test(Type, typename boost::disable_if < and_ < not_<boost::is_same<Type, int> >, apply<always<true_>, typename Type::my_type>
::type* dummy = 0)
{ }
int main(int argc, char* argv[]) { test(int()); return 0; }
I thing sfinae should disable the above test() functions for every Type, that doesn't have a nested type my_type. Under mingw-4.5 I get: error: no matching function for call to 'test(int)' Regards, Kris

2010/12/14 Igor R <boost.lists@gmail.com>
I thing sfinae should disable the above test() functions for every Type, that doesn't have a nested type my_type.
So is it possible not to evaluate Type::my_type, if Type is int? I tried to use lazy_enable_if, but with no success...
How about adding this overload: void test( int ) { } Or if You want to disable implicit conversions to int, add this overload instead: template<typename Type> void test(Type, typename boost::enable_if< boost::is_same<Type, int>
::type* dummy = 0) { }
warning: untested Regards, Kris

How about adding this overload:
void test( int ) { }
Or if You want to disable implicit conversions to int, add this overload instead: template<typename Type> void test(Type, typename boost::enable_if< boost::is_same<Type, int>
::type* dummy = 0) { }
Well, it was just minimal reproducing sample... In my real code I look-up some type in an mpl::map, then I have to call a function, IF the type was found (i.e. it's not mpl::void_) AND its inner type passes meta-function filter. So the code looks like this: typedef at<my_map, my_type>::type found_type; process(found_type()); template<typename Type> void process(Type, typename boost::enable_if < and_ < not_<is_same<Type, void_> >, typename apply<filter, typename Type::inner_type>::type >
::type* dummy = 0) { .... }

2010/12/14 Igor R <boost.lists@gmail.com>
How about adding this overload:
void test( int ) { }
Or if You want to disable implicit conversions to int, add this overload instead: template<typename Type> void test(Type, typename boost::enable_if< boost::is_same<Type, int>
::type* dummy = 0) { }
Well, it was just minimal reproducing sample... In my real code I look-up some type in an mpl::map, then I have to call a function, IF the type was found (i.e. it's not mpl::void_) AND its inner type passes meta-function filter. So the code looks like this:
typedef at<my_map, my_type>::type found_type; process(found_type());
template<typename Type> void process(Type, typename boost::enable_if < and_ < not_<is_same<Type, void_> >, typename apply<filter, typename Type::inner_type>::type
::type* dummy = 0)
{ .... }
But do the solutions I proposed to Your simplified example compile on Your compiler? If they do, what's wrong with applying them to your process() funcions? Kris

But do the solutions I proposed to Your simplified example compile on Your compiler? If they do, what's wrong with applying them to your process() funcions?
Ah, sorry, I judged too quickly... You're right, adding a simple overload for int (or for void_ in my real case) seems to be exactly what I need. Thanks a lot!
participants (2)
-
Igor R
-
Krzysztof Czainski