0

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?

meddle0106
  • 1,292
  • 1
  • 11
  • 22
  • 2
    This is not about the parameter pack, but about a [non-deduced context](http://stackoverflow.com/questions/25245453/what-is-a-nondeduced-context). The compiler cannot figure out what combinations of `FArgs` could result in which `Handle` type. – Bo Persson Jun 16 '16 at 10:06
  • 2
    [C++, template argument can not be deduced](http://stackoverflow.com/q/6060824/3953764) – Piotr Skotnicki Jun 16 '16 at 10:16
  • Typically new questions should be asked as new, separate questions; not edited into existing ones/, – TylerH Jun 16 '16 at 13:57
  • Added a new question under http://stackoverflow.com/questions/37874287/enable-template-only-for-specifc-templated-class – meddle0106 Jun 17 '16 at 06:09

0 Answers0