Question

I have code, that compiles and runs as expected in gcc and doesn't compile in MSVC 2012 RC, i can't explain why, so it's bug in MSVC, or my code is incorrect?

#include <boost/mpl/vector.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/size.hpp>
#include <boost/utility/enable_if.hpp>
#include <vector>
#include <iostream>

namespace mpl = boost::mpl;

template<typename T,
typename = void>
struct Some
{
   typedef std::vector<T> type;
};

template<typename T>
struct Some<T, typename boost::enable_if_c<mpl::is_sequence<T>::type::value>::type> :
    public Some<typename mpl::front<T>::type>::type
{
};


int main()
{
   typedef mpl::vector<int, double> vect_t;
   typedef Some<vect_t> vector;
   vector vect;
   vect.push_back(1);
   std::cout << "int: " << vect.at(0) << std::endl;
}

http://liveworkspace.org/code/45d78872a2c7f30192277a81c655b471

MSVC says, that push_back and at are not members of Some<vect_t>.

EDIT.

It looks like bug in MSVC 2012 since

#include <boost/mpl/vector.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/size.hpp>
#include <boost/utility/enable_if.hpp>
#include <vector>
#include <iostream>

namespace mpl = boost::mpl;

template<typename T, typename = void>
struct Some
{
    typedef std::vector<T> type;
};

template<typename T>
struct Some<T, typename boost::enable_if_c<mpl::is_sequence<T>::type::value>::type> :
    public std::vector<int>
{
};


int main()
{
   typedef mpl::vector<int, double> vect_t;
   typedef Some<vect_t>::type vector;
   vector vect;
   vect.push_back(1);
   std::cout << "int: " << vect.at(0) << std::endl;
}

gives errors, that i can't push_back int into std::vector<boost::mpl::vector<int, double> >, so it choose general-case, not specialization...

EDIT.

Strange... But this works as expected

template<typename T>
struct Some<T, typename std::enable_if<boost::mpl::is_sequence<T>::value>::type> :
    public std::vector<int>
{
};

So, i can't explain why, but MSVC 2012 cannot works with nested expressions in enable_if (or possibly in template parameters).

template<typename T>
struct is_int : public std::integral_constant<bool, false>
{
};

template<>
struct is_int<int> : public std::integral_constant<bool , true>
{
};

template<typename T, typename = void>
struct Some
{
    typedef void type;
};

template<typename T>
struct Some<T, typename std::enable_if<is_int<T>::type::value>::type>
{
    static_assert(is_int<int>::type::value, "asserted");
    typedef T type;
};

int main()
{
    static_assert(is_int<T>::type::value, "ass");
    Some<int>::type t = 0;
}
Was it helpful?

Solution

I compile and run your code in MSVC 2010 successfully, so probably this is a bug in RC version of MSVC 2012. so event try it in MSVC 2012 final or wait for MSVC 2012 Express.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top