g ++ лямбда, объявленная с использованием локального типа ... используется, но никогда не определяется - неужели ошибка? - PullRequest
0 голосов
/ 26 апреля 2018

g ++ не скомпилирует этот код без -fpermssive.Ни лязг, ни 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 голосов
/ 26 апреля 2018

Да, это возможно:

заголовочный файл

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;
}

Демо

0 голосов
/ 26 апреля 2018

Вы не сможете определить wrapped_foo в любом другом модуле компиляции, потому что каждый лямбда-тип уникален.Таким образом, хотя этот код технически действителен, он никогда не сможет соединиться.G ++ просто идет немного дальше и также отказывается компилировать это.

Также вот более простой код для воспроизведения проблемы:

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

void func(){
    wrapped_foo();
}
...