Reputation: 810
I wrote this piece of code in order to check if a std::map
contains a specific key:
template<typename T, typename... Args >
inline bool contains(const std::map<Args...>& map, const T& value) noexcept
{
static_assert(std::is_constructible_v< decltype(map)::key_type , T >);
return map.find(value) != std::end(map);
}
I have the following error:
error:
key_type
is not a member ofconst std::map<std::__cxx11::basic_string<char>, Query>&
What is the problem with decltype(map)::key_type
?
Upvotes: 10
Views: 940
Reputation: 2623
The earlier answer explained the reason for the error, which does answer the question, but I wanted to expand on the solution to the problem:
Instead of converting the value back into its type to get the key_type
, you can grab it from the type directly:
template <class T, class ... Args >
inline bool contains(const std::map<Args...>& map, const T& value) noexcept
{
using Key = typename std::map<Args...>::key_type;
static_assert(std::is_constructible_v<Key, T>);
return map.find(value) != std::end(map);
}
demo (Note that the code in the question uses C++17
syntax, despite the C++11
tag)
But I think a better solution is to name the appropriate template type:
template <class T, class Key, class ... Args >
inline bool contains(const std::map<Key, Args...>& map, const T& value) noexcept
{
static_assert(std::is_constructible_v<Key, T>);
return map.find(value) != std::end(map);
}
Upvotes: 0
Reputation: 37606
The error is quite explicit, decltype(map)
is const std::map<Args... >&
, which is a const
-reference to a std::map
. Since it's a reference type, it does not have a ::key_type
.
You need to use std::remove_reference_t
to drop the reference:
static_assert(std::is_constructible_v<
typename std::remove_reference_t<decltype(map)>::key_type,
T
>);
You need the typename
because std::remove_reference_t<decltype(map)>
is a dependent name.
A more idiomatic way would be to use a Map
template parameter and not constrain the function to std::map
:
template<typename T, typename Map>
inline bool contains(const Map &map, const T& value) noexcept {
static_assert(std::is_constructible_v< typename Map::key_type , T >);
return map.find(value) != std::end(map);
}
Upvotes: 10