Dev
Dev

Reputation: 493

What does "std::decay_t<U> (until C++20) std::remove_cvref_t<U> (since C++20)" mean?

Can someone explain to me in detail what this sentence means?

template< class U = T >
optional& operator=( U&& value );

4) ...The function does not participate in overload resolution unless std::decay_t<U> (until C++20) std::remove_cvref_t<U> (since C++20) is not std::optional<T>...

(source)

In the 4th version, what does it mean to write "std::decay_t<U> (until C++20) std::remove_cvref_t<U> (since C++20)" without any verb? Is there a typo?

Upvotes: 3

Views: 1850

Answers (1)

John Kugelman
John Kugelman

Reputation: 361809

It's subtle—there's a box around the two classes that indicates a sub-phrase. Pretend there's an "or" between them and read it like this:

The function does not participate in overload resolution unless [ std::decay_t<U> (until C++20) or std::remove_cvref_t<U> (since C++20) ] is not std::optional<T>...

You could read it as two alternate sentences:

  • The function does not participate in overload resolution unless std::decay_t<U> is not std::optional<T>... (until C++20)

  • The function does not participate in overload resolution unless std::remove_cvref_t<U> is not std::optional<T>... (since C++20)

(In C++20 they tightened up the spec and replaced decay with remove_cvref. The two do essentially the same thing but the latter is more surgically precise. decay, like remove_cvref, removes qualifiers; but it also turns arrays into pointers, which isn't germane here.)

In English, it's essentially saying:

The function does not participate in overload resolution unless U—ignoring &, &&, const, and volatile—is not std::optional<T>...

In other words, overload (4) is only useable under certain conditions. If those conditions aren't met then perfect forwarding is taken off the table; presumably, SFINAE is used to disable it.

Upvotes: 3

Related Questions