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..