Подтвердить что ты не робот

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

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

Пример: (проверено с помощью 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: этот вопрос несколько связан с моим другим вопросом о constexpr std:: tuple, поскольку std::forward не будучи constexpr является технической причиной, почему std::tuple не может быть создан путем вызова его cstr с rvalues, но этот вопрос здесь явно (намного) более общий.

4b9b3361

Ответ 1

Общий ответ заключается в том, что рабочая группа Комитета по библиотекам С++ не провела исчерпывающий трал в рамках рабочего проекта, в котором рассматриваются возможности использования новых основных средств. Эти функции использовались там, где люди имели время и склонность смотреть на возможные виды использования, но нет времени для исчерпывающей проверки.

Есть несколько работ, касающихся дополнительных видов использования constexpr в работе, например, в ноябрь 2010 г..