Ответ 1
Просто возьмите текущую версию GCC (8.0.0 в это время), и она будет построена. Руководство по вычитанию шаблона для std::set
просто не реализовано в старой версии stdlib для 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
просто не реализовано в старой версии stdlib для GCC.
std::set
были добавлены только в gcc HEAD.Согласно gcc-mirror/gcc
в GitHub, директивы дедукции для конструктора итераторов std::set
были добавлены и объединены в libstdС++ - 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
Это, естественно, объясняет, почему вывод шаблона шаблона терпит неудачу для шаблонов set
конструкторами итераторов (s) для более ранних версий gcc, например. 7.2.0. Если используется текущая магистраль gcc (gcc HEAD 8.0.0 20171103 (экспериментальная)) доступны руководства по вычитанию выше, а вывод аргумента шаблона успешно также для конструкторов итераторов.
Что касается вывода аргумента шаблона в gcc 7.2.0 для конструкторов std::initializer_list
(без указаний на вывод, которые также были добавлены в фиксации выше), что было несколько объяснено в @удаленный ответ JohnZwinck, эти конструкторы сами не замаскированы (не параметризованы их собственным списком параметров шаблона), но используйте set
тип члена value_type
- это просто typedef из set
параметр первого шаблона Key
- аргумент шаблона в список std::initializer
, который я бы предположил, чтобы получить достаточно простой путь вычитания, чтобы преуспеть даже без и явного руководства по вычитанию.