cs_signal
cs_signal copied to clipboard
Cannot create connection to function with different exception specifier
The following will not compile due to the 'noexcept' specifier on the activate() function:
class Receiver: public CsSignal::SlotBase
{
public:
Receiver ();
void activate () noexcept;
};
class Sender: public CsSignal::SignalBase
{
public:
Sender ();
SIGNAL_1 (void send ());
SIGNAL_2 (send);
};
int main(int argc, char *argv[])
{
Sender transmitter;
Receiver radio;
connect (transmitter, &Sender::send, radio, &Receiver::activate);
return 0;
}
with the following error:
cs_internal.h(432): error C2825: 'T': must be a class or namespace when followed by '::'
cs_signal.h(341): note: see reference to class template instantiation 'CsSignal::Internal::Bento<void (__cdecl Receiver::* )(void) noexcept>' being compiled
main.cpp(12): note: see reference to function template instantiation 'bool CsSignal::connect<Sender,Sender,,Receiver,void(__cdecl Receiver::* )(void) noexcept>(const Sender &,void (__cdecl Sender::* )(void),const Receiver &,T,CsSignal::ConnectionKind,bool)' being compiled
with
[
Sender=Sender,
Receiver=Receiver,
T=void (__cdecl Receiver::* )(void) noexcept
]
cs_internal.h(432): error C2653: 'T': is not a class or namespace name
cs_internal.h(432): error C2269: cannot create a pointer or reference to a qualified function type (requires pointer-to-member)
cs_internal.h(435): error C2825: 'T': must be a class or namespace when followed by '::'
cs_internal.h(435): error C2653: 'T': is not a class or namespace name
cs_internal.h(435): error C2535: 'void CsSignal::Internal::Bento<void (__cdecl Receiver::* )(void) noexcept>::invoke_internal(const CsSignal::Internal::TeaCupAbstract *,MethodReturn (__cdecl *)(MethodArgs...)) const': member function already defined or declared
cs_internal.h(432): note: see declaration of 'CsSignal::Internal::Bento<void (__cdecl Receiver::* )(void) noexcept>::invoke_internal'
This is with CsSignal 1.2.3 and Visual Studio CE 2022.
Making the send() function noexcept does not help.
I am not sure if there is an easy solution. The 'noexcept' specification is part of the function type but I don't know if it is used for scope resolution (e.g. matching function type to function by the compiler, like const vs. non-const). Adding a copy of invoke_internal() with a noexcept specifier did not help...
It appears that the 'noexcept' is being deduced as part of the data type passed into CsSignal::Internal::Bento, which results in an instantiation of a template which does not exist. As a possible workaround, I would try casting the slot method pointer to remove the noexcept specifier in your call to connect:
connect (transmitter, &Sender::send, radio, static_cast<void (Receiver::*)()>(&Receiver::activate));
Will this work for your use case?
We have added a task on our roadmap to look at a more general solution.
For now that is an acceptable workaround. Thank you for looking into this.