Разрешение микрофона

Проблема заключается не в make_tuple, а в конструкторе перемещения tuple в libstdc ++ (gcc4.8.2).

Для шаблонов классов функции-члены генерируются только при использовании. Спецификация noexcept также откладывается аналогично, см., Например, Проблема CWG 1330 .

При инициализации переменной из make_tuple конструктор перемещения создается, даже если он отменен (например, чтобы проверить, плохо ли он сформирован). Вот почему вы видите разницу между , просто определяющей переменную tuple и , используя make_tuple .

Конструктор перемещения имеет условный noexcept который реализуется рекурсивно. Поэтому для каждого аргумента шаблона требуется постоянное количество дополнительных экземпляров. Выдержка из вывода ошибки clang ++ при превышении максимальной глубины реализации: (скопируйте себя, стена текста, входящая)

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:803:24: note: in instantiation of default argument for '__test, std::_Tuple_impl &&>' required here
      static true_type __test(int);
                       ^~~~~~~~~~~
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:803:24: note: while substituting deduced template arguments into function template '__test' [with _Tp = std::_Tuple_impl, _Arg = std::_Tuple_impl &&, $2 = ]
      static true_type __test(int);
                       ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:117:14: note: in instantiation of template class 'std::__is_direct_constructible_impl, std::_Tuple_impl &&>' requested here
    : public conditional::type
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:818:14: note: in instantiation of template class 'std::__and_ >, std::__is_direct_constructible_impl, std::_Tuple_impl &&> >' requested here
    : public __and_,
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:896:14: note: in instantiation of template class 'std::__is_direct_constructible_new_safe, std::_Tuple_impl &&>' requested here
    : public conditional::value,
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:904:39: note: in instantiation of template class 'std::__is_direct_constructible_new, std::_Tuple_impl &&>' requested here
    : public integral_constant, std::_Tuple_impl &&>' requested here
    : public __is_direct_constructible
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:956:39: note: in instantiation of template class 'std::__is_constructible_impl, std::_Tuple_impl &&>' requested here
    : public integral_constant, std::_Tuple_impl &&>' requested here
    : public conditional::type
                         ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:1042:14: note: in instantiation of template class 'std::__and_, std::_Tuple_impl &&>, std::__is_nt_constructible_impl, std::_Tuple_impl &&> >' requested here
    : public __and_,
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:1073:14: note: in instantiation of template class 'std::is_nothrow_constructible, std::_Tuple_impl &&>' requested here
    : public is_nothrow_constructible
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:1079:14: note: in instantiation of template class 'std::__is_nothrow_move_constructible_impl, false>' requested here
    : public __is_nothrow_move_constructible_impl
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:117:14: note: in instantiation of template class 'std::is_nothrow_move_constructible >' requested here
    : public conditional::type
             ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/tuple:268:16: note: in instantiation of template class 'std::__and_, std::is_nothrow_move_constructible > >' requested here
      noexcept(__and_,
               ^
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/type_traits:802:24: note: in instantiation of exception specification for '_Tuple_impl' requested here
             = decltype(::new _Tp(declval()))>

Мы можем видеть здесь реализацию, например. из is_nothrow_move_constructible в терминах is_nothrow_constructible, который реализован в терминах __is_nt_constructible и т. д., для 15 уровней инстанцирования. Это напечатано как стек вызовов, поэтому вы можете следить за экземплярами, начиная со дна.


Это означает, что для каждого аргумента шаблона для tuple требуется 15 дополнительных уровней инстанцирования для этой проверки. Кроме того, всегда требуются 9 уровней (постоянная глубина).

Поэтому 17 аргументов требуют глубины создания 17 * 15 + 9 == 264.

16
задан deimos1988 18 July 2014 в 05:31
поделиться