Mor*_*enn 2 c++ templates rvalue-reference template-templates c++11
由于可变参数模板,我前一段时间实现了C++等效的Python链函数.该函数用于连续迭代许多容器.这是使用名为的生成器的函数的旧工作版本ChainedObject,无论它是什么:
template<typename... Iterables>
auto chain(Iterables&&... iters)
-> ChainObject<Iterables...>
{
return /* ... */;
}
Run Code Online (Sandbox Code Playgroud)
相应的主要内容:
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;
}
Run Code Online (Sandbox Code Playgroud)
那个主要工作正常.我们不关心ChainObject中的问题,所以让我们看看它.我尝试使用模板模板来确保使用的不同集合具有相同value_type的功能chain,并通过以下方式修改函数:
template<typename T, template<typename...> class... Iterables>
auto chain(Iterables<T>&&... iters)
-> ChainObject<T, Iterables...>
{
return /* ... */;
}
Run Code Online (Sandbox Code Playgroud)
我认为这会做的伎俩,以保证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&'
似乎问题来自于参数传递给采用右值引用的函数.但是,我真的不明白为什么我的第一个版本工作正常,并注意使用模板模板.
你的问题是T&&模板魔法仅适用于类型参数(它可以通过推断T,例如.int&如果需要,可以用于左值参数).它不适用于模板模板参数,其中实际类型是X<T>&&- X在这种情况下必须是类模板,而不是像"引用到类模板"那样.所以最后你必须传递一个rvalue-reference,你不能从lvalue(变量)隐式得到它.
也就是说,我建议你回复你的早期代码,并检查value_typess是否与SFINAE相同(或兼容,等等,无论你得到什么).
粗糙的代码草图(严格相等):
template <class ... Ts> struct all_types_equal
{
static const bool value = false;
};
template <class T>
struct all_types_equal<T>
{
static const bool value = true;
};
template <class T, class ... Rest>
struct all_types_equal<T, T, Rest...>
{
static const bool value = all_types_equal<T, Rest...>::value;
};
template<typename... Iterables>
auto chain(Iterables&&... iters)
-> typename std::enable_if<all_types_equal<Iterable::value_type...>::value, ChainObject<Iterables...> >::type
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1293 次 |
| 最近记录: |