如果我的实例是 stl 映射,我如何获取模板的类型?

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

我想要一个 get_value 模板函数。

请看下面代码:

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);
}

如您所见,模板函数应该有一个 return 类型,这取决于实例的第二种类型,有什么方法可以让我获得这种类型以使代码可运行?

std::map<K,V> 中的“第二种”称为std::map<K,V>::mapped_type。但是,您可以使用 auto 让编译器为您推断:

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,
}

或显式类型:

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,
}

如果您可以使用 C++14 标准或更高版本,最安全的方法是使用 decltype(auto) 作为 return 类型:

template<typename T>
decltype(auto) get_value(const T& m, int key);

与普通 auto 的区别在于 decltype(auto) 保留了 cv 限定符,在您的情况下,您很可能希望转发与 std::map 完全相同的类型。

例如,由于实际代码使用 std::map<int, std::map<std::string, int>>,您可能希望避免每次都复制 return 值,而 decltype(auto) 将实现这一点。