2

I have a question about this code:

    explicit constexpr
    optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
    noexcept(is_nothrow_constructible_v<_Tp, initializer_list<_Up>&,
                        _Args...>)
    : _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }

Why is the reference used here? Initializer list is passed to std::optional as value. I guess it might be related with the fact that it is a named argument in this context, but I am not sure.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
wehin19066
  • 33
  • 4

1 Answers1

2

When you use is_nothrow_constructible and various other type traits, there is a convention that an lvalue reference type T& means "lvalue of type T" whereas a non-reference type T means "rvalue of type T". In this case, a test is being done to see whether _Tp is nothrow constructible given that the first argument will be an lvalue of type initializer_list<_Up>.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • Where is such behaviour documented? And moreover, should'nt `T&&` be used for rvalues? – wehin19066 Nov 08 '21 at 23:02
  • @wehin19066 See https://eel.is/c++draft/meta.unary.prop – Brian Bi Nov 08 '21 at 23:04
  • Forgive me if I am wrong but I can't find anything about it on the page you mentioned. Can you elaborate on this topic? I thought that these traits should work in a simple manner like: `is_nothrow_constructible`, `is_nothrow_constructible` or `is_nothrow_constructible`. – wehin19066 Nov 09 '21 at 10:26
  • 1
    @wehin19066 The definition of `is_nothrow_constructible` references `is_constructible`. Paragraph 8 mentions how `is_constructible` uses `declval`. `declval()` returns `T&&`. According to reference collapsing rules, if `T` is `U&`, then `T&&` is `U&`. In other words an lvalue reference type supplied to `declval` will yield an lvalue argument. – Brian Bi Nov 09 '21 at 15:13
  • One more question. How should one act while using traits like is_nothrow_constructible with forwarding references? Is it necessary to specify `&` in such case? – wehin19066 Nov 09 '21 at 15:52
  • @wehin19066 That question deserves a separate post, because it's a different question. – Brian Bi Nov 09 '21 at 15:57
  • Answer for future readers: In case of forwarding references you can simply use `T` in traits, collapsing will figure everything out. – wehin19066 Nov 09 '21 at 16:08