在 C++11 中,是否可以从具有指定模板参数的模板 class 中获取通用模板 class?
In C++11 is there anyway to get the general template class from a template class with specified template arguments?
(例如从 std::list<some_value_type>
得到 std::list
)
考虑以下代码:
#include <list>
#include <string>
std::string combine(int val, std::string str)
{
return std::to_string(val) + str;
}
template <class T, class U>
auto foo(const T &container, const U &val)
-> std::list<U>
{
using RetType = std::list<U>;
RetType result;
for(auto item : container) {
result.push_back(combine(item, val));
}
return result;
}
int main()
{
std::list<int> numbers = {1, 2, 3, 4, 5};
std::list<std::string> result = foo(numbers, std::string(" potato"));
return 0;
}
这可以编译,但我希望它以不同的方式工作。我想要 foo
到 return 与传递给它的第一个参数相同类型的容器,但它的值类型更改为第二个参数的类型,即类型 U
.
所以如果 foo
作为第一个参数传入 std::list<int>
并且 std::string
作为第二个参数传入,它 returns std::list<std::string>
。或者,如果 foo
作为第一个参数传入 std::vector<int>
并且 std::string
作为第二个参数传入,则它 return 为 std:: vector<std::string>
。等等。
基本上我想用实现上述功能的东西替换 std::list<U>
的两个实例,可能使用 <type_traits>
.
的工具
在 C++11 中有没有办法做到这一点?我找到的唯一解决方案是为我想使用的每种容器类型创建 foo
的重载版本,但如果有一种涵盖所有容器类型的通用方法,我会更喜欢。
是的,您可以使用 模板模板参数 并将每次出现的 list<T>
更改为通用 C<T>
:
template <template<class...>class C, class T, class U>
auto
foo(const C<T> &container, const U &val) -> C<U>
{
using RetType = C<T>;
// ...
}
一种常用的替代方法是使用迭代器,迭代器是容器元素的通用接口。可以使用的标准算法是std::transform
:
transform(numbers.begin(), numbers.end(), inserter(result, result.begin()), [] (int n) {
return combine(n, " potato");
});
(例如从 std::list<some_value_type>
得到 std::list
)
考虑以下代码:
#include <list>
#include <string>
std::string combine(int val, std::string str)
{
return std::to_string(val) + str;
}
template <class T, class U>
auto foo(const T &container, const U &val)
-> std::list<U>
{
using RetType = std::list<U>;
RetType result;
for(auto item : container) {
result.push_back(combine(item, val));
}
return result;
}
int main()
{
std::list<int> numbers = {1, 2, 3, 4, 5};
std::list<std::string> result = foo(numbers, std::string(" potato"));
return 0;
}
这可以编译,但我希望它以不同的方式工作。我想要 foo
到 return 与传递给它的第一个参数相同类型的容器,但它的值类型更改为第二个参数的类型,即类型 U
.
所以如果 foo
作为第一个参数传入 std::list<int>
并且 std::string
作为第二个参数传入,它 returns std::list<std::string>
。或者,如果 foo
作为第一个参数传入 std::vector<int>
并且 std::string
作为第二个参数传入,则它 return 为 std:: vector<std::string>
。等等。
基本上我想用实现上述功能的东西替换 std::list<U>
的两个实例,可能使用 <type_traits>
.
在 C++11 中有没有办法做到这一点?我找到的唯一解决方案是为我想使用的每种容器类型创建 foo
的重载版本,但如果有一种涵盖所有容器类型的通用方法,我会更喜欢。
是的,您可以使用 模板模板参数 并将每次出现的 list<T>
更改为通用 C<T>
:
template <template<class...>class C, class T, class U>
auto
foo(const C<T> &container, const U &val) -> C<U>
{
using RetType = C<T>;
// ...
}
一种常用的替代方法是使用迭代器,迭代器是容器元素的通用接口。可以使用的标准算法是std::transform
:
transform(numbers.begin(), numbers.end(), inserter(result, result.begin()), [] (int n) {
return combine(n, " potato");
});