GNOME Bugzilla – Bug 132187
G++-3.4 Prerelease: Problem calling Glib::wrap in containers.h in G++-3.4.
Last modified: 2004-12-22 21:47:04 UTC
This seems to be an issue in both glibmm 2.2 and 2.3 as well, so I'm filing it here in 2.4 glibmm rather than 2.2 gtkmm, though I've only tested it in 2.2. The following code: #include <gtkmm.h> int main(int argc, char *argv[]) { Gtk::Menu menu; menu.items().back(); } gives the following error in g++ 3.4 prerelease: /usr/include/gtkmm-2.0/glibmm/containers.h: In member function `typename Glib::List_Iterator_Base<T_IFace>::reference Glib::List_Cpp_Iterator<T_Impl, T_IFace>::operator*() const [with T_Impl = GtkMenuItem, T_IFace = Gtk::MenuItem]': /usr/include/gtkmm-2.0/glibmm/containers.h:349: instantiated from `const typename T_Base::reference Glib::List_ConstIterator<T>::operator*() const [with T_Base = Glib::List_Cpp_Iterator<GtkMenuItem, Gtk::MenuItem>]' /usr/include/gtkmm-2.0/glibmm/helperlist.h:106: instantiated from `T_Child& Glib::HelperList<T_Child, T_CppElement, T_Iterator>::back() const [with T_Child = Gtk::MenuItem, T_CppElement = const Gtk::Menu_Helpers::Element, T_Iterator = Glib::List_Cpp_Iterator<GtkMenuItem, Gtk::MenuItem>]' originalold.cc:6: instantiated from here /usr/include/gtkmm-2.0/glibmm/containers.h:225: error: no matching function for call to `wrap(GtkMenuItem*)' /usr/include/gtkmm-2.0/glibmm/wrap.h:55: note: candidates are: Glib::RefPtr<Glib::Object> Glib::wrap(GObject*, bool) /usr/include/gtkmm-2.0/glibmm/main.h:363: note: Glib::RefPtr<Glib::MainContext> Glib::wrap(GMainContext*, bool) /usr/include/gtkmm-2.0/glibmm/main.h:399: note: Glib::RefPtr<Glib::MainLoop> Glib::wrap(GMainLoop*, bool) the culprit is in glibmm: reference operator*() const { if (node_ && node_->data) return *Glib::wrap(static_cast<T_Impl*>((*node_).data)); return *(pointer)glibmm_null_pointer; } Translation: I can't use overloadings declared before template definition. I've been told by someone on #gcc this isn't a bug. Here's a reduced test case: class A; class B; class C; namespace ns { void func(A*); void func(B*); template<class TP> struct TestClass { static void test() { ns::func(static_cast<TP *>(0)); } }; void func(C*); } int main(int argc, char *argv[]) { ns::TestClass<C>::test(); } In this case, the problem can be fixed by removing the qualification off the function call, as in: func(static_cast<TP *>(0)); or for the original code: return *wrap(static_cast<T_Impl*>((*node_).data)); which is OK as it's already in the ns/Glib namespace. Apparently if you use an unqualified function call, it's then argument dependent (Koenig) lookup rules, and these rules allow an overloading declared between definition and instantiation.
> I can't use overloadings declared before template definition *after* template definition, that is.
Apparently it's a G++ bug that it's accepted without the qualification. The only solution apparently is to move the overloading before the definition.
An API breaking fix for this would be to change the wrapping to static methods instead of functions, then I believe the call would be dependent and therefore looked up at instantiation time.
Hmm, so the template needs to be #included after the wrap() functions that it uses. That's a pain, but I'll definitely (try to) deal with this before gtkmm 2.4.0.
Note: This seems to be this item in the g++ 3.4 Changes document: http://gcc.gnu.org/gcc-3.4/changes.html "In templates, all non-dependent names are now looked up and bound at definition time (while parsing the code), instead of later when the template is instantiated."
I think I have fixed this in cvs now (see the attached glibmm_gcc34.patch). Let's hope that this does not become a more general problem. I now get an internal compiler error in cellrenderer_generation.cc, so I'd like you to try too. Everything else builds if I comment that code out.
Created attachment 25613 [details] [review] glibmm_gcc34.patch