Я создал макрос, который удобно строит лямбда-функции, используя которые я могу перебирать тензорные объекты в библиотеке, которую я написал. Однако вложение этих макросов, по-видимому, приводило к тому, что GCC подвергался внутренней ошибке сегментации. Расширив выходные данные препроцессора компилятора и пройдя через метод проб и ошибок, я обнаружил, что причиной, по-видимому, является использование decltype
в списке параметров вложенной лямбда-функции, объявленной в методе класса или структуры. Ниже приведен минимальный пример использования стандартной библиотеки.
#include <iostream>
#include <type_traits>
template <class Iterator, class Func>
void for_each(const Iterator first, const Iterator last, Func func)
{
for (Iterator it = first; it != last; ++it) {
func(*it);
}
}
template <class T>
class helper
{
typedef typename T::size_type type;
};
template <class T>
class helper<T&>
{
typedef typename T::size_type type;
};
template <class T>
class helper<T*>
{
typedef typename T::size_type type;
};
struct bar
{
struct foo
{
typedef int size_type;
} foo_;
void test()
{
int arr[] = { 1, 2, 3 };
for_each(arr, arr + 3, [&](int i) {
/*
** XXX: The "typename ... type" segfaults g++!
*/
for_each(arr, arr + 3, [&](typename helper<decltype(foo_)>::type j) {
});
});
}
};
int main()
{
return 0;
}
Выход компилятора:
$ g++ -Wall -std=c++0x nested_lambda.cpp
nested_lambda.cpp: In lambda function:
nested_lambda.cpp:42:56: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.6/README.Bugs> for instructions.
Preprocessed source stored into /tmp/ccqYohFA.out file, please attach this to your bugreport.
Сначала я решил использовать decltype
, потому что объект передается макросу, и мне нужно извлечь тип объекта. Исходя из типа объекта (T
, T&
или T*
), я использовал бы класс черт, чтобы T::size_type.
size_type
был бы тогда типом параметров лямбда-функции.
Как можно обойти эту проблему, не используя typedef для предварительного объявления типа параметра функции лямбда? Если вы можете подумать о каком-то другом решении, которое можно легко реализовать в макросе (то есть, многократно копировать и вставлять в список параметров лямбда-функции), это тоже сработает.