Как правило, мне нужна оболочка функции static_cast
для использования в качестве предиката (для преобразования), так как static_cast
напрямую не может использоваться таким образом. На этот раз лямбда не является предпочтительной. Моя реализация:
template<typename T>
struct static_cast_forward{
template<class U>
T operator()(U&& u) const {
return static_cast<T>(std::forward<U>(u));
}
};
Во-первых, хотя у меня есть фундаментальное понимание ссылок на rvalue и т. Д. Я хочу проверить, является ли это правильным способом реализации этого forward / wrapper?
Во-вторых, спросить, если какая-либо библиотека std
или boost
уже обеспечивает эту функцию?
Дополнительно: вы бы отправили другие приведения таким же образом?
ФАКТИЧЕСКИЙ СЛУЧАЙ:
Мой фактический случай - использовать с boost::range
, что-то вроде:
//auto targetsRange = mixedRange | boost::adaptors::filtered(TYPECHECK_PRED) | boost::adaptors::transformed(static_cast_forward<TARGET_PTR_TYPE>());
ПРИМЕРЫ РАБОТЫ:
#include <algorithm>
template<typename T>
struct static_cast_forward {
template<class U>
T operator()(U&& u) const {
return static_cast<T>(std::forward<U>(u));
}
};
//example 1:
void test1() {
std::vector<double> doubleVec{1.1, 1.2};
std::vector<int> intVec;
std::copy(doubleVec.begin(), doubleVec.end(), intVec.end());//not ok (compiles, but gives warning)
std::transform(doubleVec.begin(), doubleVec.end(), std::back_inserter(intVec), static_cast_forward<int>()); //ok
}
//example 2:
struct A {
virtual ~A() {}
};
struct B : public A {
};
struct C : public A {
};
void test2() {
std::vector<A*> vecOfA{ new B, new B};
std::vector<B*> vecOfB;
//std::transform(vecOfA.begin(), vecOfA.end(), std::back_inserter(vecOfB), static_cast<B*>); //not ok: syntax error..
std::transform(vecOfA.begin(), vecOfA.end(), std::back_inserter(vecOfB), static_cast_forward<B*>() ); //ok
}