Giriş
std::forward'ın ne işe yaradığını uzun bir süre anlayamadım. Genellikle template kodlarında kullanılıyor. Daha sonra std::forward'ın static_cast<T&&> ile aynı şey olduğunu görünce herşey daha açık hale geldi. Metodun içi şöyle. Yani t parametresini r-vlue haline getiriyor.
std::forward() metodu Perfect Forwarding olarak tanımlı template metodlarda kullanılır.
std::forward her zaman T parametresi ile kullanılır.
Örnek
Şu kullanım şekli yanlıştır.
Elimizde şöyle bir kod olsun. Bu kod derlenmez.
Bazı kodlarda şöyle yapılıyor. Bir farkı var mı bilmiyorum
std::forward method dispatching için kullanılabilir.
std::forward'ın ne işe yaradığını uzun bir süre anlayamadım. Genellikle template kodlarında kullanılıyor. Daha sonra std::forward'ın static_cast<T&&> ile aynı şey olduğunu görünce herşey daha açık hale geldi. Metodun içi şöyle. Yani t parametresini r-vlue haline getiriyor.
template< class T >
T&& forward( typename std::remove_reference<T>::type& t );
Daha okunaklı hali şöyletemplate <class T>
T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
Scott Meyers'in "Effective Modern C++" kitabındaki açıklaması şöyleBu konuyu mükemmel açıklayan cevap burada.Item 23:Understand std::move and std::forward
...
The story for std::forward is similar to that for std::move, but whereas std::move unconditionally casts its argument to an rvalue, std::forward does it only under certain conditions. std::forward is a conditional cast. It casts to an rvalue only if its argument was initialized with an rvalu.
...
Given that both std::move and std::forward boil down to casts, the only difference being that std::move always casts, while std::forward only sometimes does, you might ask whether we can dispense with std::move and just use std::forward everywhere. From a purely technical perspective, the answer is yes: std::forward can do it all. std::move isn’t necessary. Of course, neither function is really necessary, because we could write casts everywhere, but I hope we agree that that would be, well, yucky.
...
std::move's attractions are convenience, reduced likelihood of error, and greater clarity...
std::forward() metodu Perfect Forwarding olarak tanımlı template metodlarda kullanılır.
std::forward her zaman T parametresi ile kullanılır.
Örnek
Şu kullanım şekli yanlıştır.
T&& param
std::forward(param)
Şöyle kullanmak gerekir.std::forward<T>(param);
ÖrnekElimizde şöyle bir kod olsun. Bu kod derlenmez.
template<typename... Args>
Wrapper(Args&&... args) : x(std::make_unique<X>(std::forward(args)...)) {}
Şöyle yaparız. Sebebi ise derleyicinin args'a bakarak tipleri çıkaramaması.std::forward<Args>(args)...
ÖrnekBazı kodlarda şöyle yapılıyor. Bir farkı var mı bilmiyorum
std::forward<T&&>(param);
r-value method dispatchstd::forward method dispatching için kullanılabilir.
class OraclePreparedStatement
{
public:
template<typename T>
void bind_param(uint32_t col_index, T&& param)
{
bind_param_impl(col_index, std::forward(param),
std::is_integral<std::remove_reference_t<T>>());
}
private:
template<typename T>
void bind_param_impl(uint32_t col_index, T&& param, std::true_type)
{
statement->setNumber(col_index, oracle::occi::Number(param));
}
template<typename T>
void bind_param_impl(uint32_t col_index, T&& param, std::false_type)
{
statement->setString(col_index, std::forward<T>(param));
}
OracleConnection::StatementWrapper statement;
};
Bu metodu haliyle şöyle çağırabiliyoruz.OraclePreparedStatement stmt;
auto col_index = 1;
stmt.bind_param(col_index++, 15);
stmt.bind_param(col_index++, std::string("test string"));
Hiç yorum yok:
Yorum Gönder