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