#3730 closed Bugs (wontfix)
compilation problem with is_virtual_base_of when class contains abstract methods
Reported by: | Owned by: | John Maddock | |
---|---|---|---|
Milestone: | Boost 1.42.0 | Component: | type_traits |
Version: | Boost 1.41.0 | Severity: | Problem |
Keywords: | Cc: | manfred.doudar@… |
Description
When a virtual base class contains an abstract method that is implemented in the inheritance tree, rather than the final class, gcc won't compile serialized classes. This happens with gcc 4.3.1 on openSuSE 11.0 and gcc 4.4.1 on 11.2.
I'm attaching a modified version of the test_diamond.cpp program from the serialization library. The base class now contains an abstract method, the final class in the example has been renamed to intermediate and a new final class is derived directly from intermediate. The abstract method is implemented in the intermediate class resulting in a compiler error
/usr/local/boost-r58233/include/boost/type_traits/is_virtual_base_of.hpp:56: error: no unique final overrider for ‘virtual void base::method1()’ in ‘boost::detail::is_virtual_base_of_impl<intermediate, final, mpl_::bool_<true> >::X’
The method looks to be unique to me. If the method is implemented in final rather than intermediate then the problem doesn't occur.
Attachments (1)
Change History (9)
by , 13 years ago
Attachment: | test_diamond2.cpp added |
---|
comment:1 by , 13 years ago
I can't at present see a way to fix this, here's a reduced test case:
#include <map> #include <iostream> #include <boost/type_traits.hpp> class base { public: base() : i(0) {} base(int i) : i(i) { m[i] = "text"; } virtual void method1() = 0; virtual ~base() {}; private: int i; std::map<int, std::string> m; }; class derived1 : virtual public base { public: }; class derived2 : virtual public base { public: }; class intermediate : public derived1, public derived2 { public: intermediate() {} intermediate(int i) : base(i) {} void method1(); }; void intermediate::method1() { } class final : public intermediate { public: final() {} final(int i) : base(i) {} }; // // This class demonstrates what we need to make work inside is_virtual_base_of. // MSVC compiles this just fine (likewise is_virtual_base_of), and only complains // when attempting to use method1. Other compilers (GCC, Intel on Linux) complain // as soon as X is declared, likewise when instantiating is_virtual_base_of. // struct X : final, virtual intermediate { X(); X(const X&); X& operator=(const X&); ~X()throw(); }; int main( int /* argc */, char* /* argv */[] ) { X x; x.method1(); boost::is_virtual_base_of<intermediate, final>::type t; return t.value != true; }
comment:2 by , 13 years ago
Cc: | added |
---|
Since Final inherits from Intermediate, and X from both - you in effect have a "diamond" since X can take a path either through Final or Intermediate. In which case:
class final : public virtual intermediate
should resolve matters, no?
comment:3 by , 12 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Class Final is defined outside our control - that's the issue - I'm closing this as "unfixable" for now.
comment:4 by , 12 years ago
What happens next? will it be removed from release versions of the library? or modified so it at least compiles?
comment:5 by , 12 years ago
Nothing happens next - unless someone can come up with a fix - as far as anyone can tell it's simply not possible to make the trait work in every possible case like this - since the trait isn't part of the next std the only solution for occational difficult cases like this, is for the user to supply a specialisation of is_virtual_base_of.
HTH, John.
example program to reproduce problem