为什么std::forward会丢弃constexpr属性?

12

由于未声明为constexprstd::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 ,但是这里的问题显然(更)普遍。

1
快速说明,以 _[A-Z] 开头的标识符为编译器实现者保留。因此,您的程序构造不正确。 - Matthieu M.
4
如果你曾经转移到Windows系统,那么_T就会变得特别讨厌,因为它是一个宏。 - Bo Persson
1
@Matthieu M,@Bo Persson 谢谢。我将所有名称_T替换为T等,以便其他人可以更安全/更轻松地尝试代码。 - Lars
1个回答

10

一般来说,C++委员会的库工作组并没有仔细查找工作草案中使用新核心功能的机会。这些功能是在有人有时间和意愿查看可能的用途时使用的,但没有足够的时间进行详尽的检查。

目前有一些关于constexpr额外用途的论文正在进行,例如那些在2010年11月邮件中的论文。


谢谢。我已经知道相关文档N3231,但它没有提到std::forward的20.3.3节。--你提供的更多是“社会原因”。我对“概念原因”感兴趣,即使将std::forward constexpr化是否有问题或是否可以接受? - Lars
4
乍一看,我没有看到任何不可以的理由。 - Anthony Williams
由于在constexpr函数中传递和调用函数指针的问题报告(并且文字函数对象类型已经可以是constexpr),使std :: forward不是constexpr似乎是不幸的。 - Johannes Schaub - litb
5
N3305 提议为 std::forward 添加 constexpr。 - Dave Abrahams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接