0

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

JVApen
  • 11,008
  • 5
  • 31
  • 67
  • 2
    Have you tried just a single `template`, with three template parameters? – Sam Varshavchik Aug 04 '19 at 20:20
  • Not yet, it that works, I'm gonna be confused on why that would be the right way of writing this – JVApen Aug 04 '19 at 20:21
  • Well, why wouldn't it be? – Sam Varshavchik Aug 04 '19 at 20:23
  • Looks like that was the trick. Why did they make that inconsistent with defining a function? – JVApen Aug 04 '19 at 20:24
  • @JVApen It deduces `_Mutex` from the argument type. For example, what if you had `unique_lock>` instead? – Artyer Aug 04 '19 at 20:24
  • @Artyer I'm pretty convinced that should work and I would write it in a way that it explicitly deduces as you suggest.,However, I didn't design `std::unique_lock` and I expect it might misbehave if you move the mutex. (However, as that's not a good idea, I'm not that worried about it) – JVApen Aug 04 '19 at 20:29
  • why did you split in 2 template? one by argument? – Jarod42 Aug 04 '19 at 20:31
  • As for defining a function outside of the class definition, that's the way you write it – JVApen Aug 04 '19 at 20:32
  • @JVApen For template member functions of template classes, the first template is deduced from `this`. Since there is no `this`, there would be no way to deduce that separately from the arguments so it doesn't make sense – Artyer Aug 04 '19 at 20:52
  • Forgive me if I'm wrong, but aren't `_Names` beginning with underscore followed by a capital letter reserved? – Fureeish Aug 04 '19 at 21:03
  • 1
    @Fureeish: they are, I explicitly used an example from the standard library as example for familiarity. I've copied the Ctor from MSVCs implementation – JVApen Aug 04 '19 at 21:12

1 Answers1

5

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.

Joel Filho
  • 1,300
  • 1
  • 5
  • 7