g ++ lambda声明使用本地类型...使用但从未定义 - 真的是一个错误?

时间:2018-04-26 02:07:55

标签: c++ lambda g++

g ++不会在没有-fpermssive的情况下编译此代码。 clang和icc都不抱怨。这段代码合法吗?

我的目的是在一个编译单元中声明wrapped_foo并在单独的编译单元中定义它。这可能吗?

bug1.cpp

auto wrap(int (*f)(int)){
    return [f](int i) {
        return f(i);
    };
}

int foo(int);
extern decltype(wrap(foo)) wrapped_foo;

int func(){
    return wrapped_foo(2);
}
garden with -m gcc/7.3.0-01c7/bin g++ -Wall -Wextra  bug1.cpp -c
bug1.cpp:8:28: error: ‘wrap(int (*)(int))::<lambda(int)> wrapped_foo’, declared using local type ‘wrap(int (*)(int))::<lambda(int)>’, is used but never defined [-fpermissive]
 extern decltype(wrap(foo)) wrapped_foo;
                            ^~~~~~~~~~~

2 个答案:

答案 0 :(得分:2)

是的,有可能:

头文件

inline auto wrap(int (*f)(int))
{
    return [f](int i) {
        return f(i);
    };
}

int foo(int i);
extern decltype(wrap(&foo)) wrapped_foo;

cpp文件

int foo(int i) { return i;}
decltype(wrap(foo)) wrapped_foo = wrap(&foo);

使用

int func(){
    return wrapped_foo(42);
}

int main() {
    std::cout << func() << std::endl;
}

Demo

答案 1 :(得分:1)

您无法在任何其他编译单元中定义wrapped_foo,因为每个lambda类型都是唯一的。因此,尽管此代码在技术上是有效的,但它永远不会成功链接。 G ++只是更进一步,并拒绝编译它。

这里还有一个更简单的代码来重现这个问题:

auto l = [](){};
extern decltype(l) wrapped_foo;

void func(){
    wrapped_foo();
}