Why does std::forward discard constexpr-ness?
Being not declared constexpr
, std::forward
will discard constexpr-ness for any function it forwards arguments to. Why is std::forward
not declared constexpr
itself so it can preserve constexpr-ness?
Example: (tested with g++ snapshot-2011-02-19)
#include <utility>
template <typename T> constexpr int f(T x) { return -13;}
template <typename T> constexpr int g(T&& x) { return f(std::forward<T>(x));}
int main() {
constexpr int j = f(3.5f);
// next line does not compile:
// error: ‘constexpr int g(T&&) [with T = float]’ is not a constexpr function
constexpr int j2 = g(3.5f);
}
Note: technically, it would be easy to make std::forward
constexpr, e.g., like so (note that in g std开发者_如何学编程::forward
has been replaced by fix::forward
):
#include <utility>
namespace fix {
/// constexpr variant of forward, adapted from <utility>:
template<typename Tp>
inline constexpr Tp&&
forward(typename std::remove_reference<Tp>::type& t)
{ return static_cast<Tp&&>(t); }
template<typename Tp>
inline constexpr Tp&&
forward(typename std::remove_reference<Tp>::type&& t)
{
static_assert(!std::is_lvalue_reference<Tp>::value, "template argument"
" substituting Tp is an lvalue reference type");
return static_cast<Tp&&>(t);
}
} // namespace fix
template <typename T> constexpr int f(T x) { return -13;}
template <typename T> constexpr int g(T&& x) { return f(fix::forward<T>(x));}
int main() {
constexpr int j = f(3.5f);
// now compiles fine:
constexpr int j2 = g(3.5f);
}
My question is: why is std::forward
not defined like fix::forward
?
Note2: this question is somewhat related to my other question about constexpr std::tuple as std::forward
not being constexpr
is the technical reason why std::tuple
cannot be created by calling its cstr with rvalues, but this question here obviously is (much) more general.
The general answer is that the C++ committee's Library Working Group have not done an exhaustive trawl through the working draft looking for opportunities to use the new core facilities. These features have been used where people have had the time and inclination to look at possible uses, but there is not the time for exhaustive checking.
There are some papers regarding additional uses of constexpr
in the works, such as those in the November 2010 mailing.
精彩评论