简体   繁体   English

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

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

I have a std::set which allows deduction from an iterator range. 我有一个std::set ,它允许从迭代器范围中扣除。

#include <iostream>
#include <set>

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

The above program failed to compile in GCC. 上述程序未能在GCC中编译。

Why does deduction fail for std::set here? 为什么std::set演绎失败?

Just take the current GCC version (8.0.0 at this time) and it will build. 只需采用当前的GCC版本(此时为8.0.0)即可构建。 The template deduction guide for std::set just doesn't seem to be implemented in the older GCC version's stdlib. std::set的模板推导指南似乎没有在较旧的GCC版本的stdlib中实现。

Deduction guides for the iterators constructors of std::set was only recently added to gcc HEAD. std::set的迭代器构造函数的推导指南最近才被添加到gcc HEAD中。

According to gcc-mirror/gcc at GitHub, the deduction guides for std::set 's iterators constructor(s) was added and merged to libstdc++-v3 less than two weeks ago , 根据GitHub上的gcc-mirror/gccstd::set的迭代器构造函数的演绎指南已添加并在不到两周前合并到libstdc ++ - v3

(Extract from diff for libstdc++-v3/include/bits/stl_set.h ) (从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 

This naturally explains why template argument deduction fails for the templated set by iterator(s) constructors for earlier versions of gcc, eg 7.2.0. 这自然解释了为什么模板参数推导对于早期版本的gcc(例如7.2.0)的迭代器构造函数的模板set失败了。 If using the current gcc trunk ( gcc HEAD 8.0.0 20171103 (experimental) ) the deduction guides above are available , and the template argument deduction is successful also for the iterator(s) constructors. 如果使用当前的gcc trunk( gcc HEAD 8.0.0 20171103(实验性),则可以使用上面的推论指南 ,并且对于迭代器构造函数,模板参数推导也是成功的。

As for why the template argument deduction is successful already in gcc 7.2.0 for the std::initializer_list constructors (without deduction guides; guides that was also added in the commit above), as was somewhat explained in @JohnZwinck deleted answer , these constructors are not templated themselves (not parameterized by their own template parameter list), but use set 's member type value_type —which is simply a typedef of the set 's first template type parameter Key —as template argument to the std::initializer list, which I would assume results in a simple enough deduction path to succeed even without and explicit deduction guide. 至于为什么模板参数推导在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.

相关问题 为什么这个模板参数推导在 GCC 而不是 Clang 上失败? - Why does this template argument deduction fail on GCC but not Clang? 为什么模板参数推导/替换失败了std :: tuple和模板派生类? - Why does template argument deduction/substitution fail with std::tuple and template derived classes? 为什么这样编译,模板推导应该失败? - Why does this compile, Template deduction should fail? 为什么 std::endl 的类型推导失败? - Why does the type deduction for std::endl fails? 为什么此模板参数推导/重载解析失败? - Why does this template argument deduction/overload resolution fail? 为什么在使用 typedef 时类推导指南会失败? - Why does the class deduction guide fail when using a typedef? 为什么模板参数推导/替换在这里失败? - Why does template argument deduction/substitution fail here? 为什么类型推导失败(非指针)函数类型 - Why does type deduction fail on (non-pointer-to) function types 为什么此函数指针的可变参数模板参数推导失败? - Why does the variadic template argument deduction fail for this function pointer? 为什么在给出默认值时此模板参数推断失败? - Why does this template argument deduction fail when a default value is given?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM