C++ 如何编写一个函数,该函数采用;嵌套的;模板类型作为参数
我想编写一个通用函数,它采用一些类似于map的类型,并返回map中的所有键。我还希望函数的API非常简单,如下所示:C++ 如何编写一个函数,该函数采用;嵌套的;模板类型作为参数,c++,c++17,C++,C++17,我想编写一个通用函数,它采用一些类似于map的类型,并返回map中的所有键。我还希望函数的API非常简单,如下所示: std::unordered_map<int, std::string> stringTable; auto stringTableKeys = keys(stringTable); // should return a std::vector<int> std::map<std::string, double> doubleTable; a
std::unordered_map<int, std::string> stringTable;
auto stringTableKeys = keys(stringTable); // should return a std::vector<int>
std::map<std::string, double> doubleTable;
auto doubleTableKeys = keys(doubleTable); // should return a std::vector<std::string>
std::无序映射字符串表;
自动stringTableKeys=键(stringTable);//应该返回一个std::vector
std::map双表;
自动双表键=键(双表);//应该返回一个std::vector
我不希望它绑定到std::map或std::unordered_map,也不希望绑定到特定的键或值类型,因此我尝试编写以下内容:
template <typename Key, typename Value, template <typename, typename...> typename Table>
std::vector<Key> keys(const Table<Key, Value>& table)
{
std::vector<Key> keys;
keys.reserve(table.size());
for (const auto& [key, value] : table)
keys.push_back(key);
return keys;
}
模板
标准::向量键(常数表和表)
{
向量键;
keys.reserve(table.size());
用于(常数自动和[键,值]:表)
按键。向后推(按键);
返回键;
}
但是,如果我想使用这个版本的keys()函数,我必须这样调用它
auto stringTableKeys = keys<int, std::string, std::unordered_map>(stringTable);
自动stringTableKeys=键(stringTable);
如何在keys()的定义中指定模板,以便调用方不必指定类型?很抱歉造成混淆,事实证明我的代码确实有效。 这只是Visual Studio 2019中的一个bug,我不确定它是否能正常工作,因为它说这是一个语法错误: 您介绍的代码。然而,它也有一些问题 如果输入映射类型使用不同于默认值的模板参数,它将无法编译。这是因为
键
签名不会推导出表
的模板参数,前两个参数除外。例如,这样调用键将失败:
std::map<int, std::string, std::greater<int>> stringTable;
auto stringTableKeys = keys(stringTable); // the deduced type of table argument
// does not match that of stringTable
这是我的建议
但是,如果参数的类型与预期的template typename表
签名不匹配(其中第一个模板参数表示密钥类型),则仍会中断。为了缓解这种情况,可以使用由所有关联容器定义的嵌套key\u类型
或value\u类型
类型。例如:
template <typename Container>
std::vector<typename Container::key_type> keys(const Container& table)
{
std::vector<typename Container::key_type> keys;
keys.reserve(table.size());
for (const auto& [key, value] : table)
keys.push_back(key);
return keys;
}
模板
std::向量键(常量容器和表)
{
向量键;
keys.reserve(table.size());
用于(常数自动和[键,值]:表)
按键。向后推(按键);
返回键;
}
或:
模板
std::vector>
键(常量容器和表)
{
std::vector>键;
keys.reserve(table.size());
用于(常数自动和[键,值]:表)
按键。向后推(按键);
返回键;
}
请注意,所有关联容器的Container::value_type
都是std::pair
,并且std::pair
定义了第一个_type
和第二个_type
嵌套的typedef以访问其元素类型。我们需要使用std::remove_const_t
来消除键类型的const
限定
后一版本的keys
特别有用,因为它不仅适用于关联容器,还适用于std::pair
s的任何序列。查看代码。如果您的函数已经依赖于您编写的基于范围的for
循环正确工作的假设,我不确定您是否会因为使用键类型而失去更多的通用性。例如,只需将MapType
作为类模板参数,并返回std::vector
。我是否遗漏了什么;您的尝试似乎是?这是您生成代码时的编译器错误,还是IDE中出现错误?@cigien没有编译器错误,只有IDE错误。我在您的屏幕截图中没有看到任何显示“语法错误”的内容,只有一些。让您的编译器拥有最终决定权,而不是不一致的感觉。:)
template <typename Container>
std::vector<typename Container::key_type> keys(const Container& table)
{
std::vector<typename Container::key_type> keys;
keys.reserve(table.size());
for (const auto& [key, value] : table)
keys.push_back(key);
return keys;
}
template <typename Container>
std::vector<std::remove_const_t<
typename Container::value_type::first_type>>
keys(const Container& table)
{
std::vector<std::remove_const_t<
typename Container::value_type::first_type>> keys;
keys.reserve(table.size());
for (const auto& [key, value] : table)
keys.push_back(key);
return keys;
}