First off, sorry for unclear question title, feel free to edit if you think of a better way to state it.
I have a class:
template <typename ...Arguments>
class CSignal
{
template <typename ...ActualArguments>
void invoke(ActualArguments&&... args) const {}
};
And another one, this is what I have a problem with:
class SomeClass
{
template<typename ...Arguments>
void invokeQueued(CSignal<Arguments...>& signal, const Arguments&... args)
{
m_queue.emplace_back([=](){signal.invoke(args...);});
}
std::deque<std::function<void (void)>> m_queue;
};
Problem:
CSignal<float> signal;
int i = 0;
SomeClass().invokeQueued(signal, i);
Error:
template parameter 'Arguments' is ambiguous
could be 'float'
or 'int'
Possible naive solution
template<typename ...FormalArguments, typename ...ActualArguments>
void invokeQueued(CSignal<FormalArguments...>& signal, const ActualArguments&... args)
{
m_queue.emplace_back([=](){signal.invoke(args...);});
}
is not acceptable in this specific case, because I need to capture the arguments by value (copy them into the lambda), and the conversion from ActualArguments
to FormalArguments
must occur at the time invokeQueued
is called, not when the lambda is called.
If I could typedef
the arguments pack in the CSignal
class, I would do:
template<typename ...FormalArguments>
void invokeQueued(CSignal<FormalArguments...>& signal, const CSignal<FormalArguments...>::argument_types&... args)
{
m_queue.emplace_back([=](){signal.invoke(args...);});
}
But it doesn't seem possible. Solutions?