12

宣言されていない場合constexprstd::forward引数を転送する関数のconstexpr-nessは破棄されます。constexpr-nessを維持できるように、それ自体が宣言されていないのはなぜですか?std::forwardconstexpr

例:(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::forwardconstexprを作成するのは簡単です。たとえば、次のようになります(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に関する他の質問とある程度関連しています。これは、cstrを右辺値で呼び出すことによって作成できない技術的な理由ですが、ここでの質問は明らかに(はるかに)より一般std::forward的ですconstexprstd::tuple

4

1 に答える 1

10

一般的な答えは、C ++委員会の図書館作業部会は、新しい中核施設を使用する機会を探すために、作業草案を徹底的に調査していないということです。これらの機能は、人々が考えられる用途を検討する時間と傾向がある場合に使用されてきましたが、徹底的なチェックの時間はありません。

2010年11月の郵送constexprなど、作品での追加使用に関する論文がいくつかあります。

于 2011-02-23T22:40:35.467 に答える