In following example I want to type-erase Callback<FArgs...>::Handle
to another class. Implementation is irrelevant for the question, so code is very minimal.
#include <memory>
template<typename... FArgs>
class Callback
{
public:
class Handle{};
};
class BaseCallbackHandle
{
};
using TypeErasedCallbackHandle = std::unique_ptr<BaseCallbackHandle>;
template<typename ...Args>
TypeErasedCallbackHandle makeTypeErasedCallbackHandle( typename Callback<Args...>::Handle handle)
{
return {};
}
int main()
{
Callback<int>::Handle h;
auto typeErasedHandle = makeTypeErasedCallbackHandle(h);
}
See also: http://coliru.stacked-crooked.com/a/171cd34a46618c14
I thought that makeTypeErasedCallbackHandle deduce the Args automatically, but I get following compile error:
clang++ -std=c++11 -O0 main.cpp && ./a.out
main.cpp:27:29: error: no matching function for call to 'makeTypeErasedCallbackHandle'
auto typeErasedHandle = makeTypeErasedCallbackHandle(h);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:19:26: note: candidate function [with Args = <>] not viable: no known conversion from 'Callback<int>::Handle' to 'typename Callback<>::Handle' for 1st argument
TypeErasedCallbackHandle makeTypeErasedCallbackHandle( typename Callback<Args...>::Handle handle)
^
1 error generated.
What am I doing wrong?
As a workaround, I can reformulate the function like that:
template<typename H>
TypeErasedCallbackHandle makeTypeErasedCallbackHandle( H handle)
{
return {};
}
This works but also allows the user to put anything into that function, not only Callback<FArgs...>::handle
.
Question has been marked as duplicate. Reason is understood. Let me ask a further question to make this a relevant issue again: Is there any way with static_assert or enable_if helpers to ensure, that in the second working example with typename H
only accepts H
that are from Callback<FArgs...>::handle
?