remarketing que etiqueta c++ templates

c++ - etiqueta - que es param



Cómo forzar a una función a aceptar solo un parámetro de referencia lvalue (3)

Y quiero asegurarme de que el parámetro de plantilla F && f solo acepte una referencia de valor no constante.

Entonces no deberías haber usado una referencia de reenvío. La idea general de reenviar es aceptar cualquier categoría de valor y conservarla para futuras llamadas. Entonces, la primera solución es no usar la técnica incorrecta aquí, y aceptar por una referencia de valor l:

template<typename T, typename F> inline auto do_with(T&& rvalue, F& f) { // As before }

Eso debería hacer que el compilador se queje bien si intentas pasar un valor en la función. Sin embargo, no impedirá que el compilador permita valores constantes ( F se deducirá como const F1 ). Si realmente desea evitar eso, puede agregar otra sobrecarga:

template<typename T, typename F> inline void do_with(T&& , F const& ) = delete;

El tipo de parámetro F const& coincidirá mejor con los valores const (y rvalues ​​también, por cierto), por lo que este será seleccionado en resolución de sobrecarga, e inmediatamente causará un error porque se elimina su definición. Los valores no constantes se enrutarán a la función que desee definir.

Aquí está mi situación:

template<typename T, typename F> inline auto do_with(T&& rvalue, F&& f) { auto obj = std::make_unique<T>(std::forward<T>(rvalue)); auto fut = f(*obj); return fut.then_wrapped([obj = std::move(obj)] (auto&& fut) { return std::move(fut); }); }

Quiero asegurarme de que el parámetro de la plantilla F&& f solo acepte una referencia de valor no const . ¿Cómo debo hacer cumplir esto?


Puede tomar f por referencia de valor static_assert y evitar valores no constantes con static_assert y is_const :

template<typename T, typename F> inline auto do_with(T&& rvalue, F& f) { static_assert(!std::is_const<F>::value, "F cannot be const"); … }

Con la introducción de constraints en C ++ 20, podrá utilizar una cláusula de requires lugar:

template<typename T, typename F> inline auto do_with(T&& rvalue, F& f) requires !std::is_const_v<F> { … }


para agregar otra solución

template<typename T, typename F> inline auto do_with(T&& rvalue, F&& f) { static_assert(!std::is_const<typename std::remove_reference<F>::type>::value, "must be non-const"); static_assert(std::is_lvalue_reference<F>::value, "must be lvalue reference"); ... }

o con SFINAE

template<typename T, typename F, typename std::enable_if<!std::is_const<typename std::remove_reference<F>::type>::value && std::is_lvalue_reference<F>::value, int>::type = 0> inline auto do_with(T&& rvalue, F&& f) { }