【发布时间】:2012-11-24 00:56:14
【问题描述】:
由于可变参数模板,我不久前实现了 Python 的链函数的 C++ 等价物。该函数用于连续迭代多个容器。这是使用名为 ChainedObject 的生成器的函数的旧工作版本,无论它是什么:
template<typename... Iterables>
auto chain(Iterables&&... iters)
-> ChainObject<Iterables...>
{
return /* ... */;
}
以及对应的main:
int main()
{
std::vector<int> vec = { 1, 2, 3, 4, 5 };
std::list<int> li = { 6, 7, 8, 9, 10, 11, 12, 13 };
for (auto& i: chain(vec, li))
{
// You can edit a range of iterables
// as if there was only one of them.
i *= 5;
std::cout << i << std::endl;
}
return 0;
}
那个主要工作正常。我们不在乎 ChainObject 中有什么问题,所以让我们看看。我尝试使用模板模板来确保使用的不同集合具有相同的value_type,并通过以下方式修改了函数chain:
template<typename T, template<typename...> class... Iterables>
auto chain(Iterables<T>&&... iters)
-> ChainObject<T, Iterables...>
{
return /* ... */;
}
我认为这样可以确保我之前的 main 中的 list 和 vector 共享相同的类型,但相反,我从 GCC 4.7.1 收到以下错误:
在函数'int main()'中:
错误:没有匹配函数调用 'chain(std::vector&, std::list&)'
注意:候选人是:
注意:
ChainObject<T, Iterables ...> chain(Iterables<T>&& ...) [with T = int; Iterables = {std::vector, std::list}]注意:没有已知的参数 2 从“
std::list<int>”到“std::list<int>&&”的转换注:
ChainObject<T, Iterables ...> chain(Iterables<T>&& ...) [with T = int; Iterables = {std::vector, std::list}]注意:没有已知的参数 2 从“
std::list<int>”到“std::list<int>&&”的转换错误:无法从 '' 推断出 'auto&'
问题似乎来自于将参数传递给采用右值引用的函数。但是,我真的不明白为什么我的第一个版本运行良好,请注意使用模板模板的版本。
【问题讨论】:
-
您是否尝试过传递左值引用而不是右值?
-
不要将模板模板与容器结合使用。一旦使用分配器,它就会失败。只需检查嵌套的
value_type是否相等。
标签: c++ templates c++11 rvalue-reference template-templates