如果我的实例是 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)
将实现这一点。
我想要一个 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)
将实现这一点。