由于未声明为constexpr
,std::forward
将丢弃其转发参数的任何函数的constexpr
性质。 为什么std::forward
本身没有声明为constexpr
以便保留constexpr
性质?
示例:(在g++快照-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);
}
注意: 从技术上讲,使
std::forward
成为constexpr很容易,例如(请注意,在g中,std::forward
已被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);
}
我的问题是:为什么
std :: forward
没有像 fix :: forward
那样定义?注2:这个问题与我关于
constexpr std :: tuple
的其他问题有些相关,因为 std :: forward
不是 constexpr
是技术原因,导致无法通过使用rvalue调用其cstr来创建 std :: tuple
,但是这里的问题显然(更)普遍。
_[A-Z]
开头的标识符为编译器实现者保留。因此,您的程序构造不正确。 - Matthieu M.