[multi_index] Another weird problem with MI on MSVC 7.1

Hi, I have a problem compiling the code snippet below with MSVC 7.1 (Intel Compiler 9.0 and GCC compile it just fine). The problem trigger is keyword "virtual" in class base inheritance - if you remove it it will compile OK. The error message is very weird: boost\type_traits\is_function.hpp(65) : error C2371: 'boost::detail::t' : redefinition; different basic types boost\type_traits\is_function.hpp(65) : see declaration of 'boost::detail::t' boost\type_traits\is_function.hpp(82) : see reference to class template instantiation '<Unknown>' being compiled boost\tuple\detail\tuple_basic.hpp(310) : see reference to class template instantiation '<Unknown>' being compiled boost\tuple\detail\tuple_basic.hpp(418) : see reference to class template instantiation '<Unknown>' being compiled boost\multi_index\detail\def_ctor_tuple_cons.hpp(33) : see reference to class template instantiation '<Unknown>' being compiled boost\multi_index_container.hpp(140) : see reference to class template instantiation '<Unknown>' being compiled Also, it is critical for reproducing to have 2 independent inheritance chains - if I remove name_record_set2 class and variable it also compiles just fine. Here is the code itself: #include <boost/multi_index_container.hpp> #include <boost/multi_index/mem_fun.hpp> #include <boost/multi_index/ordered_index.hpp> using namespace boost::multi_index; class base {}; class base_record : virtual public base { public: base_record() : id_(0) {} int get_id() const { return id_; } private: int id_; }; class name_record : public base_record {}; class name_record2 : public base_record {}; typedef multi_index_container< name_record, indexed_by< ordered_unique< BOOST_MULTI_INDEX_CONST_MEM_FUN(base_record, int, get_id) >
name_record_set;
typedef multi_index_container< name_record2, indexed_by< ordered_unique< BOOST_MULTI_INDEX_CONST_MEM_FUN(base_record, int, get_id) >
name_record_set2;
int main() { name_record_set ns; name_record_set2 ns2; ns.insert(name_record()); ns2.insert(name_record2()); return 0; } P.S. I use boost from RC_1_34 tag. -- Alexei Alexandrov

Alexei Alexandrov ha escrito:
Hi,
I have a problem compiling the code snippet below with MSVC 7.1 (Intel Compiler 9.0 and GCC compile it just fine). The problem trigger is keyword "virtual" in class base inheritance - if you remove it it will compile OK. The error message is very weird:
boost\type_traits\is_function.hpp(65) : error C2371: 'boost::detail::t' : redefinition; different basic types boost\type_traits\is_function.hpp(65) : see declaration of 'boost::detail::t' boost\type_traits\is_function.hpp(82) : see reference to class template instantiation '<Unknown>' being compiled boost\tuple\detail\tuple_basic.hpp(310) : see reference to class template instantiation '<Unknown>' being compiled boost\tuple\detail\tuple_basic.hpp(418) : see reference to class template instantiation '<Unknown>' being compiled boost\multi_index\detail\def_ctor_tuple_cons.hpp(33) : see reference to class template instantiation '<Unknown>' being compiled boost\multi_index_container.hpp(140) : see reference to class template instantiation '<Unknown>' being compiled
Hello Alexei, Well, this looks like a bug in MSVC 7.1. I've checked with other compilers, as you've also done, and everything works fine. Let's try a workaround and do a little bug hunt, OK? * The workaround: I cannot try it myself (I don't have MSVC 7.1) but possibly the following will avoid the compiler error: try using the following instead of the direct instantiation of BOOST_MULTI_INDEX_CONST_MEM_FUN: struct base_record_if_extractor: public BOOST_MULTI_INDEX_CONST_MEM_FUN(base_record, int, get_id) {}; Does this improve things? * As for why MSVC 7.1 is choking, the error trace seems to indicate that boost::is_function is having a hard time with types involving virtual inheritance. The following is an attempt at reducing the problem to its essentials. Could you try whether MSVC 7.1 still fails at this? If so, can you try to reduce the test case some more? *********BEGIN CODE********* #include <boost/type_traits/is_function.hpp> struct foo{}; struct bar: virtual foo { int f()const{return 0;} }; template<typename C,typename T,T (C::*P)()const> struct baz{}; template<typename T> struct qux { struct type1:boost::is_function<T>{}; struct type2:boost::is_function<T>{}; }; int main() { typedef qux<baz<bar,int,&bar::f> > type; type::type1 t1; type::type2 t2; return 0; } *********END CODE********* Looking fwd to your feedback, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Joaquín Mª López Muñoz <joaquin <at> tid.es> writes:
struct base_record_if_extractor: public BOOST_MULTI_INDEX_CONST_MEM_FUN(base_record, int, get_id) {};
Does this improve things?
Yes, with this extractor it compiles OK.
* As for why MSVC 7.1 is choking, the error trace seems to indicate that boost::is_function is having a hard time with types involving virtual
inheritance.
The following is an attempt at reducing the problem to its essentials. Could you try whether MSVC 7.1 still fails at this? If so, can you try to reduce the test case some more?
This code piece compiles just fine.

Alexei Alexandrov <alexei.alexandrov <at> gmail.com> writes:
Joaquín Mª López Muñoz <joaquin <at> tid.es> writes:
struct base_record_if_extractor: public BOOST_MULTI_INDEX_CONST_MEM_FUN(base_record, int, get_id) {};
Does this improve things?
Yes, with this extractor it compiles OK.
OK. Does this solve your original problem? Since I'm not confident we can fix the underlying problem, you'll probably have to stick to this workaround.
* As for why MSVC 7.1 is choking, the error trace seems to indicate that boost::is_function is having a hard time with types involving virtual inheritance.
The following is an attempt at reducing the problem to its essentials. Could you try whether MSVC 7.1 still fails at this? If so, can you try to reduce the test case some more?
This code piece compiles just fine.
Too bad :( Well, maybe you can start with your original snippet and start deconstructing it til you get to a simpler formulation we can present to type_traits authors (I'm afraid I can't do it myself, I don't have that compiler as I said before.) First thing I'd do, try to eliminate the use of multi_index_container and replace it with instantiations of the form boost::is_function<const_mem_fun<...> >. Please come back to me if you decide to do this. Best, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (3)
-
Alexei Alexandrov
-
Joaquin M Lopez Munoz
-
Joaquín Mª López Muñoz