Почему std :: forward отбрасывает constexpr-ness?

Не объявлено constexpr , std :: forward отбрасывает constexpr-ness для любой функции, которой он передает аргументы. Почему std :: forward не объявлен сам constexpr , чтобы сохранить constexpr-ness?

Пример: (проверено с g ++ snapshot-2011-02-19)

#include 

template  constexpr int f(T x) { return -13;}
template  constexpr int g(T&& x) { return f(std::forward(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 

namespace fix {
  /// constexpr variant of forward, adapted from :
  template
  inline constexpr Tp&&
  forward(typename std::remove_reference::type& t) 
  { return static_cast(t); }

  template
  inline constexpr Tp&&
  forward(typename std::remove_reference::type&& t) 
  {
    static_assert(!std::is_lvalue_reference::value, "template argument"
          " substituting Tp is an lvalue reference type");
    return static_cast(t);
  }
} // namespace fix

template  constexpr int f(T x) { return -13;}
template  constexpr int g(T&& x) { return f(fix::forward(x));}

int main() {
  constexpr int j = f(3.5f);
  // now compiles fine:
  constexpr int j2 = g(3.5f);
}

Мой вопрос: почему std :: forward не определен как fix :: forward ?

Note2: этот вопрос отчасти связан с моим другим вопросом о constexpr std :: tuple , поскольку std :: forward не является constexpr технической причиной, по которой std :: Кортеж не может быть создан путем вызова его cstr с rvalue, но этот вопрос здесь, очевидно, (гораздо) более общий.

12
задан Community 23 May 2017 в 11:51
поделиться