3

I am reading the cpp 23 standard and I stumbled upon std::unexpected.

Section expected.un.cons defines

template<class Err = E>
constexpr explicit unexpected(Err&& e);

with the following costraint (among others)

is_same_v<remove_cvref_t<Err>, unexpected> is false; 

When would this expression be true given that unexpected is a class template?

NotMe
  • 65
  • 5

1 Answers1

9

unexpected is the injected-class-name in the scope of the class template. It refers to the current specialization of the template. It does not refer to the template itself as the same name would outside the class scope.

For example if you write

template<typename T>
struct X {
    static X x;
};

then X<T>::x is of type X<T>. You don't have to repeat the template argument list in the declaration of x. If none is given, then it resolves to the injected-class-name which refers to the current specialization of the template with the same template argument list.

The constraint is there so that the constructor can't be chosen over the copy constructor in overload resolution, which may otherwise happen for non-const lvalue arguments.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • Do you mean the move constructor (non const lvalues)? I am trying with this code but I cannot see an effect of the constraint https://godbolt.org/z/s3MnE3463 – NotMe Mar 18 '23 at 18:24
  • 1
    @NikBomb No I mean the copy constructor without `std::move`. See https://godbolt.org/z/q691Y6aro. – user17732522 Mar 18 '23 at 18:37
  • I see, thank you! Any particular reason as to why the copy constructor should be preferred in the case of wrapper/monadic types? I see `std::optional` does something similar. – NotMe Mar 18 '23 at 18:48
  • 1
    @NikBomb The forwarding constructor tries to initialize the contained object (of type `E`) with the argument. You usually can't initialize a `E` from a `unexpected`. It would simply fail to compile or potentially have the wrong semantics if `E` has a constructor from `unexpected`. The copy constructor is supposed to copy the whole `unexpected` without details of `E` affecting it. – user17732522 Mar 18 '23 at 19:07