template <class T> inline constexpr T&& constexpr_forward(typename
std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
- What does
typename do here? Just to declare the following part is a type?
std::remove_reference<T>::type is a dependent type which depends on the template parameter T, hence we need typename to tell the compiler we are trying to use a dependent-name,
- Why do we need
std::remove_reference here? Didn't we add the reference back in the type& part?
If you check the example usage of this utility function as in here
....
template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
...
You can see, a variadic fowarding reference type is used as the explicit template argument to constexpr_foward<Args>(args).... This will preserve the value category of the type. When any of the argument is a reference, it will be as if we called that utility function with constexpr_forward<Arg01&>(arg01). And the instatiation of that template will be
inline constexpr Arg01&&& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&&&>(t);
}
and by reference collapsing rule, we have
inline constexpr Arg01& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&>(t);
}
Actually, the remove reference should be superfluous there (read about reference collapsing);
- What does "std utility functions are not constexpr yet" mean? How does this function make them constexpr? The body of it is just a
static_cast.
It does nothing more than forwarding a non-constexpr function in constexpr functions and constructor.
- This function is used in a number of constructors and it looks like this:
template <class... Args>
constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}, so what does it do here to args?
Basically as explained above..