Boost logo

Boost :

Subject: [boost] MSVC9 SFINAE quirks?
From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2009-01-07 20:18:37


Is there some gotcha about metaprogramming with MSVC9? I recently finished my geometry library rewrite and found that I couldn't port it to windows because the SFINAE overloading of generic functions is viewed as ambiguous in the more complex cases, but was readily accepted by gcc and icc in linux.

The following code compiles in recent versions of gcc, but fails in MSVC9

//simple SFINAE overload of foo works in both
template <typename T>
typename gtl_if<typename is_mutable_polygon_90_type<T>::type>::type foo(const T& t) { return gtl_yes(); }
template <typename T>
typename gtl_if<typename is_mutable_polygon_45_type<T>::type>::type foo(const T& t) { return gtl_yes(); }

//metafunction wrapper around SFINAE to supply return type works in both
template <typename T>
typename requires_1<typename gtl_if<typename is_mutable_polygon_90_type<T>::type>::type, void>::type
foo2(const T& t) { }
template <typename T>
typename requires_1<typename gtl_if<typename is_mutable_polygon_45_type<T>::type>::type, void>::type
foo2(const T& t) { }

//meta function wrapper around two checks works in gcc but not msvc9
// error C2668: 'gtl::foo4' : ambiguous call to overloaded function
template <typename polygon_type, typename polygon_type_2>
typename requires_1< typename gtl_if< typename gtl_and<
        typename is_mutable_polygon_90_type<polygon_type>::type,
        typename is_mutable_polygon_90_type<polygon_type_2>::type
>::type>::type,
  polygon_type>::type
foo4(polygon_type& polygon, const polygon_type_2& point) {return point;}
template <typename polygon_type, typename polygon_type_2>
typename requires_1< typename gtl_if< typename gtl_and<
        typename is_mutable_polygon_45_type<polygon_type>::type,
        typename is_mutable_polygon_45_type<polygon_type_2>::type
>::type>::type,
  polygon_type>::type
foo4(polygon_type& polygon, const polygon_type_2& point) {return point;}

int main()
{
        using namespace gtl;
        polygon_45_data<int> p45;
        foo(p45);
        foo2(p45);
        foo4(p45, p45); //error here

        //this works as expected and has no syntax error in msvc9
        gtl_if<gtl_and<
                is_mutable_polygon_45_type<polygon_45_data<int> >::type,
                is_mutable_polygon_45_type<polygon_45_data<int> >::type
>::type>::type a;

        //this works as expected, generating syntax error in msvc9
        // error C2039: 'type' : is not a member of 'gtl::gtl_if<gtl::gtl_no>
        gtl_if<gtl_and<
                is_mutable_polygon_90_type<polygon_45_data<int> >::type,
                is_mutable_polygon_90_type<polygon_45_data<int> >::type
>::type>::type b;

Does someone like Steve Wanatabe with more experience with MS compilers know what I have inadvertently run afoul of and how to get myself out of this jam?

Thanks,
Luke


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk