Reputation: 862
I want a get_value template function.
please see the following code:
template<typename T>
(something i want) get_value(const T& m, int key) {
auto it = m.upper_bound(key);
return it == m.begin() ? (*it).second : (*--it).second; // please notice here,
// if my instance is map<int, map<string, int>> the return type should be m.second's type
// that's map<string, int>
}
int main() {
std::map<int, std::map<std::string, int>> m;
auto& it = get_value(m, 10);
}
as you can see, the template function should have a return type, which is depend on instance's second type, is there any method i can get this type to make the code runnable?
Upvotes: 1
Views: 55
Reputation: 368
If you can use C++14 standard or above, the safest way to go would be to use decltype(auto)
as the return type:
template<typename T>
decltype(auto) get_value(const T& m, int key);
The difference to a plain auto
is that decltype(auto)
preserves cv-qualifiers, and in your case you most likely want to forward exactly the same type that std::map
gives you.
For example, since the actual code uses std::map<int, std::map<std::string, int>>
, you might want to avoid copying the return value every time, and decltype(auto)
will achieve that.
Upvotes: 0
Reputation: 122458
The "second type" in a std::map<K,V>
is called std::map<K,V>::mapped_type
. However, you can use auto
to let the compiler deduce that for you:
template<typename T>
auto get_value(const T& m, int key) {
auto it = m.upper_bound(key);
return it == m.begin() ? (*it).second : (*--it).second; // please notice here,
}
or with explicit type:
template<typename T>
typename T::mapped_type get_value(const T& m, int key) {
auto it = m.upper_bound(key);
return it == m.begin() ? (*it).second : (*--it).second; // please notice here,
}
Upvotes: 1