12

未声明constexprstd::forward将丢弃将参数转发到的任何函数的 constexpr-ness。为什么std::forward不声明constexpr自己,以便它可以保留 constexpr-ness?

示例:(使用 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);
}

注意:从技术上讲,制作 constexpr 很容易std::forward,例如,像这样(请注意,在 gstd::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不定义 like fix::forward

注意2:这个问题与我关于 constexpr std::tuple的另一个问题有些相关,因为std::forwardnot being是为什么不能通过用右值调用它的 cstr 来创建constexpr的技术原因,但这里的这个问题显然(更)更普遍。std::tuple

4

1 回答 1

10

一般的答案是,C++ 委员会的库工作组没有对工作草案进行详尽的拖网,以寻找使用新核心设施的机会。这些功能已用于人们有时间和意愿查看可能用途的地方,但没有时间进行详尽的检查。

有一些关于constexpr作品中其他用途的论文,例如2010 年 11 月的邮件

于 2011-02-23T22:40:35.467 回答