7

For some reasons, I've always thought that deduction guides must have the same noexcept-ness of the constructor to which they refer. For example:

template<typename T>
struct clazz {
    clazz(const T &) noexcept {}
};

clazz(const char &) noexcept -> clazz<int>;

That is, if the constructor is noexcept and I want it to be so also for const char &, I have to add the noexcept specifier to the deduction guide as well.

Today I worked a little with ICC and found that it has problems with noexcept on deduction guides. So far, so good. I thought it was a bug of the compiler and that's it.
However, I went to look into the standard and couldn't find any point that confirms my initial assumption. Because of that, I checked the same against clang and even if it works without problems, it seems that the noexcept on the deduction guide gets ignored in 100% of cases. On the other side, the one on the constructor affects both.

So, my question is, does it make any sense or is it required to somewhat propagate (if this makes sense at all) the noexcept-ness of the constructor also to the deduction guide or is it useless and I can just get rid of all noexcept on deduction guides?

skypjack
  • 49,335
  • 19
  • 95
  • 187
  • From [cppreference](https://en.cppreference.com/w/cpp/language/class_template_argument_deduction#User-defined_deduction_guides), syntax is `explicit-specifier(optional) template-name ( parameter-declaration-clause ) -> simple-template-id ;`; no `noexcept`... – Jarod42 Apr 09 '21 at 15:12

1 Answers1

7

The grammar for the deduction guide is defined in [temp.deduct.guide]/1 as

explicit-specifier(opt) template-name ( parameter-declaration-clause ) -> simple-template-id ;

and as you can see, it does not include a exception specifier.

This does make sense. The deduction guide doesn't actually construct anything. It is just used to tell the compiler how to get the template parameters from a set of arguments. You have a two step process, the deduction guide(s) run through overload resolution to determine the template parameters, and then the constructors are enumerated with those deduced template parameters, and overload resolution is run against the constructors.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • So clang/gcc/msvc are all incorrect [here](https://godbolt.org/z/4rnr9Ge3v) :-/ – Jarod42 Apr 09 '21 at 15:16
  • So, roughly speaking, all major compilers are wrong? Because it's true that it gets ignored, but they accept it even if the standard explicitly says that the token shouldn't be there. – skypjack Apr 09 '21 at 15:17
  • @Jarod42 I believe they are. It makes sense for them to allow it, as it is an easy thing to ignore and has no actual bearing on what happens. – NathanOliver Apr 09 '21 at 15:18
  • Well, it makes sense but it's invalid code technically speaking. – skypjack Apr 09 '21 at 15:19
  • 2
    @skypjack Yep. It's a heck of a lot less egregious then GCC's default acceptance of VLA's though. – NathanOliver Apr 09 '21 at 15:20
  • Fair enough. :) – skypjack Apr 09 '21 at 15:21
  • So, in practice, the noexcept-ness of the constructor is borrowed from the main definition, also in case of deduction guides? – skypjack Apr 09 '21 at 15:23
  • @skypjack The deduction guide doesn't need to care about it at all. All it's used for is to determine the template parameters. Once that is done, overload resolution is ran again to actually pick the constructor. – NathanOliver Apr 09 '21 at 15:27
  • TIL. It makes perfectly sense actually. Thanks for the quick answer and for the further explanation. – skypjack Apr 09 '21 at 15:28
  • 1
    @skypjack You're welcome. If you have an hour, you should give [this talk](https://www.youtube.com/watch?v=-H-ut6j1BYU) a watch. It gets into a lot of the finer details and really does a good job explaining the whole thing. Stephan T. Lavavej did a great job IMHO. – NathanOliver Apr 09 '21 at 15:31
  • I'll do it for sure. Thanks for pointing it out. – skypjack Apr 09 '21 at 15:35