繁体   English   中英

为什么在GCC中std :: set的演绎失败?

[英]Why does deduction fail for std::set in GCC?

我有一个std::set ,它允许从迭代器范围中扣除。

#include <iostream>
#include <set>

int main() 
{
   std::set s1 = {1,2,3,4}; 
   std::set s2(s1.begin(), s1.end());
}

上述程序未能在GCC中编译。

为什么std::set演绎失败?

只需采用当前的GCC版本(此时为8.0.0)即可构建。 std::set的模板推导指南似乎没有在较旧的GCC版本的stdlib中实现。

std::set的迭代器构造函数的推导指南最近才被添加到gcc HEAD中。

根据GitHub上的gcc-mirror/gccstd::set的迭代器构造函数的演绎指南已添加并在不到两周前合并到libstdc ++ - v3

(从diff中提取libstdc++-v3/include/bits/stl_set.h

  +#if __cpp_deduction_guides >= 201606 + + template<typename _InputIterator, + typename _Compare = + less<typename iterator_traits<_InputIterator>::value_type>, + typename _Allocator = + allocator<typename iterator_traits<_InputIterator>::value_type>, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + set(_InputIterator, _InputIterator, + _Compare = _Compare(), _Allocator = _Allocator()) + -> set<typename iterator_traits<_InputIterator>::value_type, + _Compare, _Allocator>; + + template<typename _Key, typename _Compare = less<_Key>, + typename _Allocator = allocator<_Key>, + typename = _RequireAllocator<_Allocator>> + set(initializer_list<_Key>, + _Compare = _Compare(), _Allocator = _Allocator()) + -> set<_Key, _Compare, _Allocator>; + + template<typename _InputIterator, typename _Allocator, + typename = _RequireInputIter<_InputIterator>, + typename = _RequireAllocator<_Allocator>> + set(_InputIterator, _InputIterator, _Allocator) + -> set<typename iterator_traits<_InputIterator>::value_type, + less<typename iterator_traits<_InputIterator>::value_type>, + _Allocator>; + + template<typename _Key, typename _Allocator, + typename = _RequireAllocator<_Allocator>> + set(initializer_list<_Key>, _Allocator) + -> set<_Key, less<_Key>, _Allocator>; + +#endif 

这自然解释了为什么模板参数推导对于早期版本的gcc(例如7.2.0)的迭代器构造函数的模板set失败了。 如果使用当前的gcc trunk( gcc HEAD 8.0.0 20171103(实验性),则可以使用上面的推论指南 ,并且对于迭代器构造函数,模板参数推导也是成功的。

至于为什么模板参数推导在gcc 7.2.0中已经成功用于std::initializer_list构造函数(没有推导指南;也在上面的提交中添加了指南),正如在@JohnZwinck删除的答案中有所解释的那样 ,这些构造函数不是自己模板化的(不是由他们自己的模板参数列表参数化),而是使用set的成员类型value_type -which只是set的第一个模板类型参数的typedef Key -as std::initializer list的模板参数,即使没有明确的演绎指南,我认为这会导致一个简单的演绎路径成功。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM