Почему std :: forward отбрасывает constexpr-ness? - PullRequest
12 голосов
/ 24 февраля 2011

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

Пример: (протестировано с 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 со значениями, но этот вопрос, очевидно, является (гораздо) более общим.

1 Ответ

10 голосов
/ 24 февраля 2011

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

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

...