Search code examples
c++templatesc++17ctad

How to define deduction guide with templated constructor?


In order to simplify my problem, I'll be using std::unique_lock as the tool to explain. std::unique_lock has a template argument, the mutex. However, it's constructor is also a template function unique_lock(TMutex &, const chrono::duration<_Rep, _Period>&).

When one uses this, one can write:

 auto lock = std::unique_lock(my_mutex, 5s);

So, the question: How to write out the deduction guide for this (without changing behavior), how to do so?

My best attempt upto now:

template<typename _Mutex>
template<typename _Rep, typename _Period>
unique_lock(_Mutex &, const chrono::duration<_Rep, _Period>&) -> unique_lock<_Mutex>;

Unfortunately, clang doesn't accept this:

error: extraneous template parameter list in template specialization or out-of-line template definition


Solution

  • GCC has a better error message for this:

    error: too many template-parameter-lists

    You can change it to a single template parameter list, like this:

    template<typename _Mutex, typename _Rep, typename _Period>
    unique_lock(_Mutex &, const chrono::duration<_Rep, _Period>&) -> unique_lock<_Mutex>;
    

    And it works.

    From the comments in your question, you seem to be mixing CTAD and specializations.

    You're not specializing anything in unique_lock. Not a member function, not a constructor, you're just defining a deduction guide. More specifically, from cppreference:

    The syntax of a user-defined deduction guide is the syntax of a function declaration with a trailing return type [...] A deduction guide is not a function [...]

    Notice that it has a syntax of a declaration, not a specialization. It's just different from what you expected.