After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 306705 - Can't overload methods based on different slot<> parameters.
Can't overload methods based on different slot<> parameters.
Status: RESOLVED WONTFIX
Product: libsigc++
Classification: Bindings
Component: adaptors
2.0.x
Other Linux
: Normal minor
: ---
Assigned To: libsigc++ maintainer(s)
libsigc++ maintainer(s)
Depends on:
Blocks:
 
 
Reported: 2005-06-06 20:03 UTC by Matt Fowles
Modified: 2018-07-11 07:28 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
patch: Improve the possibility to overload functions with slot parameters (5.30 KB, patch)
2014-04-02 13:45 UTC, Kjell Ahlstedt
none Details | Review

Description Matt Fowles 2005-06-06 20:03:23 UTC
Version details: 2.0.10
Distribution/Version: Debian

The following code fails to compile with the following error message:

mfowles@fowles:~/test$ cat ambiguous.cpp 
#include <sigc++/slot.h>

void use(const sigc::slot1<void, int>& s) { s(2); }
void use(const sigc::slot0<void>& s) { s(); }
void dummy(int a) { a++; }

int main(int argc, char** argv) {
    use(sigc::ptr_fun(dummy));
    return 0;
} 

mfowles@fowles:~/test$ gcc ambiguous.cpp `pkg-config --cflags sigc++-2.0`
ambiguous.cpp: In function `int main(int, char**)':
ambiguous.cpp:8: error: call of overloaded `use(sigc::pointer_functor1<int, 
   void>)' is ambiguous
ambiguous.cpp:3: error: candidates are: void use(const sigc::slot1<void, int>&)
ambiguous.cpp:4: error:                 void use(const sigc::slot0<void>&)
mfowles@fowles:~/test$ 


This can eventually be traced back to the templated constructor for sigc::slot1
and sigc::slot0.  One might be able to solve this by having a functor_baseN
class which all functors of N arguments inherit from and then providing a
constructor for slotN which takes a functor_baseN argument.  I am not deeply
familiar with the code base however, so this might not be simple or correct.

One can explicitely construct the slot they want as a workaround, but extra
typing always sucks.
Comment 1 Murray Cumming 2005-06-07 13:11:02 UTC
Did this work with previous versions of libsigc++? I think it's always been this
way.
Comment 2 Matt Fowles 2005-06-07 14:34:54 UTC
I don't know.  I would guess that it has always been this way, but I am very
unfamiliar with sigc++.
Comment 3 André Klapper 2011-09-22 09:02:18 UTC
[Resetting QA Contact and Assignee to default - see bug 659799 for more info]
Comment 4 Kjell Ahlstedt 2014-04-02 13:45:40 UTC
Created attachment 273479 [details] [review]
patch: Improve the possibility to overload functions with slot parameters

Like Matt has noticed in the bug description, the problem is the constructor
  template <class T_functor>
  slot(const T_functor& _A_func);

The declaration gives the impression that a slot can be constructed from any
other type. That's not really true, but the compiler detects that only when
it tries to instantiate the constructor and digs into its definition.
Overload resolution only considers function declarations, not definitions.

My patch tries to eliminate this constructor when instantiation would fail.
It succeeds only partially. In many cases it fails when the constructor
parameter is a sigc adaptor. These adaptors have templated function call
operators whose declarations accept any number of parameters of any type.

The patch requires a compiler with C++11 support. It's probably too early
to push it. I'm not even sure it should ever be pushed. I leave it here,
hoping that someone can improve on it. Since there is a fairly easy workaround
for the problem, a solution is not really important.

Workaround: In the code in comment 0, replace
  use(sigc::ptr_fun(dummy));
by
  use(sigc::slot<void, int>(sigc::ptr_fun(dummy)));
Then the parameter is an exact match of one of overloaded use() functions.

> One might be able to solve this by having a functor_baseN
> class which all functors of N arguments inherit from and then providing a
> constructor for slotN which takes a functor_baseN argument.

I have not studied such a solution very closely, but I suspect that it would
also at best be a partial solution. What if the overloaded slots take the same
number of parameters, but with different types? And what about the adaptors
that pretend to accept any number of parameters? Probably they must be split
into different classes that derive from adaptor_baseN.

Of course C++11 did not exist, when this bug was filed.
I think that libsigc++ can make much use of C++11. E.g. the code can probably
shrink quite a lot with variadic templates. And sigc::is_base_and_derived<>
can be replaced by std::is_base_of<>. I don't volunteer for a complete rewrite
of libsigc++.
Comment 5 Murray Cumming 2016-03-03 12:24:49 UTC
This slightly-updated test case is for both sigc++-2.0 and sigc++-3.0:

#include <sigc++/slot.h>

void use(const sigc::slot<void, int>& s) { s(2); }
void use(const sigc::slot<void>& s) { s(); }
void dummy(int a) { a++; }

int main(int argc, char** argv) {
    use(sigc::ptr_fun(dummy));
    return 0;
} 

We see much the same error message with libsigc++-3.0:

$ g++ test_different_slot_params.cc --std=c++14 `pkg-config sigc++-3.0 --libs --cflags`
test_different_slot_params.cc: In function ‘int main(int, char**)’:
test_different_slot_params.cc:8:29: error: call of overloaded ‘use(sigc::pointer_functor<void, int>)’ is ambiguous
     use(sigc::ptr_fun(dummy));
                             ^
test_different_slot_params.cc:3:6: note: candidate: void use(const sigc::slot<void, int>&)
 void use(const sigc::slot<void, int>& s) { s(2); }
      ^
test_different_slot_params.cc:4:6: note: candidate: void use(const sigc::slot<void>&)
 void use(const sigc::slot<void>& s) { s(); }
      ^

and with clang++:

$ clang++ test_different_slot_params.cc --std=c++14 `pkg-config sigc++-3.0 --libs --cflags`
test_different_slot_params.cc:8:5: error: call to 'use' is ambiguous
    use(sigc::ptr_fun(dummy));
    ^~~
test_different_slot_params.cc:3:6: note: candidate function
void use(const sigc::slot<void, int>& s) { s(2); }
     ^
test_different_slot_params.cc:4:6: note: candidate function
void use(const sigc::slot<void>& s) { s(); }
     ^
1 error generated.


Would you like to put something like this in libsigc++-3.0 (in the variadic_bind4 branch, at least today) with a suitable test?
Comment 6 Kjell Ahlstedt 2016-03-04 09:59:41 UTC
I'm not very fond of my patch in comment 4. It's a complicated partial fix of
a small problem with an easy workaround. I suggest that we don't implement it
unless someone insists that it's really helpful.

If you do push it, change the method name check() to something else. I learned
from bug 759315 that check() can be a preprocessor macro in Mac OS X.
Comment 7 André Klapper 2018-07-10 22:47:58 UTC
According to https://libsigcplusplus.github.io/libsigcplusplus/devel.html the issue tracker of libsigc++ is located at https://github.com/libsigcplusplus/libsigcplusplus/issues nowadays.

If the problem in this bug report still exists in a recent version of libsigc++ please file this bug report in GitHub.

Closing this report as WONTFIX as part of Bugzilla Housekeeping, as we plan to shut down GNOME Bugzilla in favor of GNOME Gitlab.
Comment 8 Kjell Ahlstedt 2018-07-11 07:28:48 UTC
WONTFIX is the right resolution for this bug report. See a short descussion at
https://mail.gnome.org/archives/libsigc-list/2018-March/msg00003.html
especially the last few lines.

The reported problem probably still exists, but it equally probably will never
be fixed.