gpt4 book ai didi

c++ - 在嵌套 Lambda 中使用 `decltype` 时出现 GCC 段错误

转载 作者:可可西里 更新时间:2023-11-01 16:48:17 26 4
gpt4 key购买 nike

我创建了一个宏,可以方便地构建 lambda 函数,使用它我可以在我编写的库中迭代张量对象。但是,嵌套这些宏似乎会导致 GCC 发生内部段错误。在扩展编译器的预处理器输出并经过一些试验和错误后,我发现原因似乎是在类或结构的方法中声明的嵌套 lambda 函数的参数列表中使用了 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,因为对象被传递给宏,我需要提取对象的类型。从对象的类型(TT&T*),我将使用特征类来提取 T: :size_type. size_type 将是 lambda 函数参数的类型。

如何在不使用 typedef 提前声明 lambda 函数参数类型的情况下规避这个问题?如果您能想到一些可以在宏中轻松实现的其他解决方案(即在 lambda 函数的参数列表中重复复制和粘贴),那也可以。

最佳答案

对于那些可能遇到类似问题的人来说,作为一个非常粗略的解决方法,我能想到的最好的标准解决方案是让宏提前声明一个 typedef,连接类似 GUID 的前缀(我个人推荐 _qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_) 和 __LINE__ 为 typedef 名称生成一些含糊不清的废话。幸运的是,这个名称不会与任何其他定义冲突。

为了确保相同的 __LINE__ 被连接起来,即使当 lambda 函数参数类型使用了 warbled 名称时,warbled 名称将需要由一个宏生成,该宏最初传递了一个宏参数,如以下代码示例所示。

#define _foo_GUID \
_qki_zbeu26_w92b27bqy_r62zf91j2n_s0a02_

#define _foo_MANGLE_IMPL2(a, b) \
a ## b

#define _foo_MANGLE_IMPL(a, b) \
_foo_MANGLE_IMPL2(a, b)

#define _foo_MANGLE(a) \
_foo_MANGLE_IMPL(_foo_GUID, a)

当将 _foo_MANGLE(__LINE__) 作为宏参数传递时,请确保有一个额外的间接级别,以便 _foo_MANGLE(__LINE__) 在使用之前得到评估.

关于c++ - 在嵌套 Lambda 中使用 `decltype` 时出现 GCC 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9029820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com