If I use the boost type erasure library in a Windows environment and C++ Builder 11.3 I get compilation errors.
In a C++ Builder 11.3 Windows vcl application I include this header file in a form's .cpp file:
#ifndef BOOST_TEST_H
#define BOOST_TEST_H
#include <boost/type_erasure/any.hpp>
#include <boost/type_erasure/any_cast.hpp>
#include <boost/type_erasure/builtin.hpp>
#include <boost/type_erasure/operators.hpp>
#include <boost/type_erasure/member.hpp>
#include <boost/type_erasure/free.hpp>
#include <boost/mpl/vector.hpp>
namespace boost {
BOOST_TYPE_ERASURE_MEMBER(ReadStatus)
}
#endif
I get this error message:
[bcc32c Error] member11.hpp(46): expected identifier
This takes me to boost header member111.hpp, line 42 (boost 1.82.0)
template<class P, template<class ...> class interface, class Sig, class Concept, class Base, class ID>
using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference<P>::value,
typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref<P>::value,
interface<Sig, Concept, Base, const ID>,
Base
>::type,
interface<Sig, Concept, Base, ID>
>::type;
The problem is that, because C++ Builder VCL for windows has already pulled in the windows headers, including combaseapi.h, which in line 170 had defined 'interface' as something else and this interferes with boost's use of it in the above code...
I can replicate the example in MSVC if my header is used in code that has already incorporated Windows.h...
I can 'fix' it by editing boost's codegear.hpp (where C++ Builder specific stuff resides) to undefine 'interface' or even change the code in member11.hpp to rename interface to interface_ (or any unique arbitrary value):
template<class P, template<class ...> class interface_, class Sig, class Concept, class Base, class ID>
using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference<P>::value,
typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref<P>::value,
interface_<Sig, Concept, Base, const ID>,
Base
>::type,
interface_<Sig, Concept, Base, ID>
>::type;
I'm not happy with either 'fix' because I don't want to edit boost and maybe get side effects later and definitely a maintenance issue going on.
Question:
Is there a better fix?
Andy
After discussions with Embarcadero support and in the boost-users mailing list, it was agreed that the best fix was to alter boost's member11.hpp as follows:
template<class P, template<class ...> class Interface, class Sig, class Concept, class Base, class ID>
using choose_member_interface = typename ::boost::mpl::if_c< ::boost::is_reference<P>::value,
typename ::boost::mpl::if_c< ::boost::type_erasure::detail::is_non_const_ref<P>::value,
Interface<Sig, Concept, Base, const ID>,
Base
>::type,
Interface<Sig, Concept, Base, ID>
>::type;
renaming interface to Interface to avoid the naming clash.
This is necessary because:
Boost's fix is simple and self-contained...
This was fixed as issue #20 in the boost type erasure library.