Page 9 - HRM-00-v1
P. 9

 LANGUAGE FEATURES
 How to Avoid Template Type Deduction in C++
  ARTICLE LINKS
 1. https://hrm.link/intention-templates
     {
node.key() = newKey; container.insert(std::move(node));
} }
W hat does this change?
First off, once we know Key we can deduce type_identity_t<Key>: it is Key, by definition. But what makes it useful is that the deduction doesn’t work the other way around: if the compiler knows Key, it doesn’t try to deduce type_identity_t<Key>.
Indeed, there could be template specializations of type_identity that define type as something different. We could even have several spe- cializations of type_identity that define type as the same thing. So you can’t deduce type_identity<Key> if you only know Key.
As a result, type_identity_t<Key> doesn’t take part in the deduction of template parameters in replace_key. Only Container does, and this is just enough for us because it allows us to deduce Key and Value.
This technique also works with std::set:
template< class T >
using not_deduced = type_identity_t<T>;
template<typename Key, typename Value>
void replace_key(std::map<Key, Value>& container,
const not_deduced<Key>& oldKey, const not_deduced<Key>& newKey)
{
auto node = container.extract(oldKey); if(!node.empty())
{
node.key() = newKey;
container.insert(std::move(node)); }
}
                             template<typename Key>
void replace_key(std::set<Key>& container,
const type_identity_t<Key>& oldKey, const type_identity_t<Key>& newKey)
{
auto node = container.extract(oldKey); if(!node.empty())
{
template<typename Key>
void replace_key(std::set<Key>& container,
const not_deduced<Key>& oldKey, const not_deduced<Key>& newKey)
{
auto node = container.extract(oldKey); if(!node.empty())
{
node.value() = newKey;
container.insert(std::move(node)); }
}
There are advantages and drawbacks to doing this. not_deduced is not a standard name, so a reader of your code won’t know it. It has to be clear enough for them to understand it means that Key won’t be used for type deduction.
On the other hand, if they don’t know the technique of using type_ identity to avoid type deduction, the code with type_identity_t in the interface will raise more than one eyebrow.
If anything, it will help you later remember why you didn’t just use Key in the interface.
What’s your opinion? Should we use an alias for type_identity_t in this context? If so, what alias would you think make the intention clearer?
You can let me know in the comments section as well as let me know any other piece of feedback you have on this post or anything else on Fluent C++. è hello@humanreadablemag.com
             } }
node.value() = newKey; container.insert(std::move(node));
A CURIOUS NAME
 What we use type_identity for is to prevent type deduction. But this is not clear in the naming of our interface. To make our intention clear- er in templates 1, we could use an alias for type_identity_t:
  September 2019 | 9
 


















































   7   8   9   10   11