c++ - 为什么 std::forward 会丢弃 constexpr-ness?

标签 c++ c++11 constants move-semantics perfect-forwarding

未声明 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);
}

注意:从技术上讲,制作 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:这个问题和我的另一个question about constexpr std::tuple有些关系。因为 std::forward 不是 constexpr 是无法通过使用右值调用其 cstr 来创建 std::tuple 的技术原因,但这这里的问题显然(更)普遍。

最佳答案

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

有一些关于 constexpr 在作品中的其他用途的论文,例如 November 2010 mailing 中的那些。 .

关于c++ - 为什么 std::forward 会丢弃 constexpr-ness?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5098069/

相关文章:

objective-c - 在 Objective-C 协议(protocol)中定义字符串常量的最佳方式是什么?

swift - 如果 "static"关键字用于在 swift 中定义常量/不可变,那么 "let"关键字有什么用?

c++ - BitBlt 问题 GDI

C++ Loader类

c++ - 为什么下面的代码用 `c++03` 编译而不用 `c++11`

c++ - 使交换更快、更容易使用和异常安全

C++——插入运算符、const关键字导致编译器错误

c++ - 在 Qt 中播放通知(频率 x)声音 - 最简单的方法?

c++ - std::allocate_shared 使用什么类型来分配内存?

c++ - 继承、后台线程和RAII