nick
nick

Reputation: 862

How can i get template's type if my instance is stl map?

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

Answers (2)

stiar
stiar

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

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Related Questions