Siendo no declarado constexpr
, std::forward
descartará la consistencia para cualquier función a la que reenvía argumentos. ¿Por qué el std::forward
no está declarado como constexpr
, por lo que puede preservar la consistencia?¿Por qué std :: forward descarta la consistencia?
Ejemplo: (probado con g ++ instantánea-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);
}
Nota: técnicamente, sería fácil de hacer std::forward
constexpr, por ejemplo, al igual que (nótese que en g std::forward
tiene sido sustituido por 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);
}
Mi pregunta es: ¿por qué no std::forward
define como fix::forward
?
Nota 2: Esta pregunta es algo relacionado con mi otra question about constexpr std::tuple como std::forward
no ser constexpr
es la razón técnica por std::tuple
no se puede crear llamando a su cstr con rvalues, pero esta pregunta aquí, obviamente, es (mucho) más general.
nota rápida, los identificadores que comienzan por '_ [A-Z]' están reservados para los implementadores del compilador. Su programa, como tal, está mal formado. –
Y _T es especialmente desagradable si alguna vez te mudas a Windows, donde es una macro ... –
@Matthieu M, @Bo Persson Gracias. Reemplacé todos los nombres _T por T, etc. para que otros puedan probar el código de forma más segura y fácil. – Lars