Hi folks,
I have some code making use of both Boost MPL (and Variant) with
occasional use of lexical_cast in some translation units. This is
working fine on Linux/Unix/MacOS X with a wide range of GCC and clang
versions. However, when porting to Windows with MS Visual Studio 2013
and Boost 1.58, I've encountered an unexpected and subtle interaction
with the MPL and Boost headers. If I include them in the "wrong" order
it leads to bizarre compile errors.
After many hours of testing, I've reduced the failure down to the
minimal testcase below. In the code sample below, there are two
#includes for boost/lexical_cast.hpp. If the first is uncommented,
compiling fails. If this is commented and the second is uncommented,
compiling succeeds! The odd thing: the critical place is before and
after defining BOOST_MPL_LIMIT_VECTOR_SIZE. In the failure case the
limit size is 20, when succeeding it's 40. The code below requires more
than 20 to successfully compile.
While it's fairly obvious with hindsight that lexical_cast is indirectly
including boost/mpl/limits/vector.hpp which is defaulting the limit to
20, the fact that the behaviour is differing between compilers is a bit
unexpected, particularly since I don't want to mess with the limit if
already set in case the users of my library need a higher limit, but
they might have used lexical_cast themselves.
Has anyone else run into this type of problem before? It's also made me
realise that using variant with MPL lists might be problematic if the
end user changes the limit and this changes the underlying type? Should
I just use vector40.hpp and ignore the limit? If I did this, do I need
to worry about the intermediate types in the code below, or do I just
need to use vector40 in place of vector<> (or in place of
vector0<>)--I'm unsure how insert_range knows which type to use or is it
vector0 in this case and I should be "allocating" space by using a
different type? [I am using vector<> in reality but tried vector0 here
to see if it made a difference]
Thanks all,
Roger
----source--------------------------------------------------------------
#include <string>
#include <vector>
#include <cstdint>
# ifndef BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
/// Disable MPL header preprocessing (to allow the following macros to
be modified).
# define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
# endif
#include
# ifndef BOOST_MPL_LIMIT_VECTOR_SIZE
/// MPL vector size limit increase.
# define BOOST_MPL_LIMIT_VECTOR_SIZE 40
# endif
//#include
# ifndef BOOST_MPL_LIMIT_LIST_SIZE
/// MPL list size limit increase.
# define BOOST_MPL_LIMIT_LIST_SIZE 40
# endif
#include
#include
#include
#include
#include
#include
#if BOOST_VERSION >= 105800
# include
#endif
typedef boost::mpl::vector non_numeric_types;
typedef boost::mpl::vector integer_types;
typedef boost::mpl::vector float_types;
typedef boost::mpl::joint_view::type numeric_types_view;
typedef boost::mpl::joint_view::type basic_types_view;
template<typename T>
struct make_vector
{
typedef std::vector<T> type;
};
typedef boost::mpl::transform_viewboost::mpl::_1 >::type list_types_view;
typedef boost::mpl::joint_view
all_types_view;
typedef boost::mpl::insert_range,
boost::mpl::end >::type, all_types_view>::type
discriminated_types;
------------------------------------------------------------------------
----error log-----------------------------------------------------------
1> Environment Variables passed to tool:
1> VS_UNICODE_OUTPUT=1500
1> C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\bin\x86_amd64\CL.exe /c
/I"D:\bioformats\cpp\cmake\..\ext\gtest-1.7.0\include"
/ID:\bioformats\cpp\lib /I"D:\bioformats\v1\bioformats-build\cpp\lib"
/I"D:\bioformats\v1\superbuild-install\include\boost-1_58"
/I"D:\bioformats\v1\superbuild-install\include" /Zi /nologo /W3 /WX- /Od
/Ob0 /D WIN32 /D _WINDOWS /D _DEBUG /D BOOST_ALL_DYN_LINK /D
BOOST_ALL_NO_LIB /D _CRT_SECURE_NO_WARNINGS /D "CMAKE_INTDIR=\"Debug\""
/D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope
/GR /Fo"testinclude.dir\Debug\\" /Fd"testinclude.dir\Debug\vc120.pdb"
/Gd /TP /errorReport:prompt /bigobj
"D:\bioformats\cpp\test\ome-bioformats\testinclude.cpp"
1> Tracking command:
1> C:\Program Files (x86)\MSBuild\12.0\bin\Tracker.exe /d "C:\Program
Files (x86)\MSBuild\12.0\bin\FileTracker.dll" /i
D:\bioformats\v1\bioformats-build\cpp\test\ome-bioformats\testinclude.dir\Debug\testinclude.tlog
/r D:\BIOFORMATS\CPP\TEST\OME-BIOFORMATS\TESTINCLUDE.CPP /b
MSBuildConsole_CancelEventa3d26d0a2f3141fdad0e9cdd682fa900 /c
"C:\Program Files (x86)\Microsoft Visual Studio
12.0\VC\bin\x86_amd64\CL.exe" /c
/I"D:\bioformats\cpp\cmake\..\ext\gtest-1.7.0\include"
/ID:\bioformats\cpp\lib /I"D:\bioformats\v1\bioformats-build\cpp\lib"
/I"D:\bioformats\v1\superbuild-install\include\boost-1_58"
/I"D:\bioformats\v1\superbuild-install\include" /Zi /nologo /W3 /WX- /Od
/Ob0 /D WIN32 /D _WINDOWS /D _DEBUG /D BOOST_ALL_DYN_LINK /D
BOOST_ALL_NO_LIB /D _CRT_SECURE_NO_WARNINGS /D "CMAKE_INTDIR=\"Debug\""
/D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope
/GR /Fo"testinclude.dir\Debug\\" /Fd"testinclude.dir\Debug\vc120.pdb"
/Gd /TP /errorReport:prompt /bigobj
"D:\bioformats\cpp\test\ome-bioformats\testinclude.cpp"
1> testinclude.cpp
1>D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/aux_/push_front_impl.hpp(45):
error C2664: 'int
boost::mpl::assertion_failed<false>(boost::mpl::assert<false>::type)' :
cannot convert argument 1 from 'boost::mpl::failed ************(__cdecl
boost::mpl::push_front_impl>::apply::REQUESTED_PUSH_FRONT_SPECIALIZATION_FOR_SEQUENCE_DOES_NOT_EXIST::*
***********)(Sequence)' to 'boost::mpl::assert<false>::type'
1> with
1> [
1> Sequence=boost::mpl::vector20,std::allocator>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>
1> , T=unsigned __int64
1> ]
1> No constructor could take the source type, or constructor
overload resolution was ambiguous
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/push_front.hpp(32)
: see reference to class template instantiation
'boost::mpl::push_front_impl>::apply'
being compiled
1> with
1> [
1> Sequence=boost::mpl::vector20,std::allocator>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>
1> , T=unsigned __int64
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/push_front.hpp(47)
: see reference to class template instantiation
'boost::mpl::push_front' being compiled
1> with
1> [
1> T1=boost::mpl::vector20,std::allocator>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>
1> , T2=unsigned __int64
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/apply_wrap.hpp(145)
: see reference to class template instantiation
'boost::mpl::push_frontboost::mpl::na,boost::mpl::na::apply'
being compiled
1> with
1> [
1> T1=boost::mpl::vector20,std::allocator>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>
1> , T2=unsigned __int64
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/apply.hpp(154)
: see reference to class template instantiation
'boost::mpl::apply_wrap2::type,T1,T2>'
being compiled
1> with
1> [
1> F=boost::mpl::push_frontboost::mpl::na,boost::mpl::na
1> , T1=boost::mpl::vector20,std::allocator>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>
1> , T2=unsigned __int64
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/aux_/reverse_fold_impl_body.hpp(151)
: see reference to class template instantiation
'boost::mpl::apply2,std::allocator<_Ty>>,std::vector,std::vector,std::vector>,std::vector>,std::vector,std::vector,std::vector,std::vector,std::vector<__int64,std::allocator<__int64>>,std::vector,std::vector,std::vector>,unsigned __int64>' being compiled
1> with
1> [
1> BackwardOp=boost::mpl::push_frontboost::mpl::na,boost::mpl::na
1> , T=signed char
1> ,
_Ty=std::basic_string
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/aux_/reverse_fold_impl_body.hpp(149)
: see reference to class template instantiation
'boost::mpl::aux::reverse_fold_impl<-1,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,I2>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iter,0>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,0>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,
2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mp
l
::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::v_iterboost::mpl::na,0>>>,Last,boost::mpl::vector0boost::mpl::na,BackwardOp,ForwardOp>'
being compiled
1> with
1> [
1> L1=boost::mpl::v_iterboost::mpl::na,0>
1> , T0=std::string
1> , T1=bool
1> ,
Vector=boost::mpl::vector8
1> , I2=boost::mpl::v_iter,0>
1> , T2=long double
1> , F=make_vector
1> , Tag=boost::mpl::void_
1> ,
Last=boost::mpl::joint_iterboost::mpl::na,0>,boost::mpl::v_iterboost::mpl::na,0>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::v_iterboost::mpl::na,0>>>
1> , BackwardOp=boost::mpl::push_frontboost::mpl::na,boost::mpl::na
1> , ForwardOp=boost::mpl::arg<1>
1> ]
1>
D:\bioformats\v1\superbuild-install\include\boost-1_58\boost/mpl/aux_/reverse_fold_impl_body.hpp(149)
: see reference to class template instantiation
'boost::mpl::aux::reverse_fold_impl<-1,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,I2>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iter,0>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,0>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,
2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::aux::transform_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mp
l
::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::joint_iter,2>,boost::mpl::v_iter,2>,boost::mpl::joint_iter,boost::mpl::v_iter,boost::mpl::v_iter,3>>>,boost::mpl::protect,boost::mpl::arg<1>>,0>>>,boost::mpl::v_iterboost::mpl::na,0>>>,Last,boost::mpl::vector0boost::mpl::na,BackwardOp,ForwardOp>'
being compiled
1> with
1> [
1> L1=boost::mpl::v_iterboost::mpl::na,0>
1> , T0=std::string
1> , T1=bool
1> ,
Vector=boost::mpl::vector8
1> , I2=boost::mpl::v_iter,0>
1> , T2=long double
1> , F=make_vector
1> , Tag=boost::mpl::void_
1> ,
Last=boost::mpl::joint_iterboost::mpl::na,0>,boost::mpl::v_iterboost::mpl::na,0>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter,8>,boost::mpl::v_iter,3>>>,boost::mpl::joint_iterstd::string,bool,2>,boost::mpl::v_iterstd::string,bool,2>,boost::mpl::joint_iter,8>,boost::mpl::v_iter