2016-08-09 1 views
10

я не могу составить следующую программу с GCC 6.1:GCC не может скомпилировать общий лямбда с этим захватом

#include <iostream> 
#include <string> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

class Foo 
{ 
public: 
    void apply() const 
    { 
     std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { print(x); }); 
    } 
private: 
    std::vector<std::string> bars_; 

    void print(const std::string& x) const 
    { 
     std::cout << x << ' '; 
    } 
}; 

int main() 
{ 
    Foo foo {}; 
    foo.apply(); 
    return 0; 
} 

сообщение об ошибке:

error: cannot call member function 'void Foo::print(const string&) const' without object 
     std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { print(x); }); 
                         ^~~~~ 
  • Изменение const auto& x к const std::string& x делает компиляция программы.

  • Изменение print(x) на this->print(x) делает компиляцию программы.

  • Все версии с Clang (версия для Apple LLVM 7.3.0 (clang-703.0.31)).

Является ли это ошибкой компилятора?

+0

Не могло ли это быть потому, что общая лямбда - это просто функция 'template', притворяющаяся не функцией' template', и вы должны также квалифицировать 'this->' в реальных функциях шаблона? IIRC ... –

+2

@underscore_d Это для зависимых баз. –

+5

clang компилирует его, возможно, его gcc-ошибку, см. Здесь: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 – marcinj

ответ

-3

Я не думаю, что компилятор обязан вывести тип, передаваемый лямбда внутри функции for_each, помните, что эта функция уже скомпилирована, как компилятор может узнать, что будет выполнять функция for_each к лямбде после того, как она прошла лямбда?

+0

Ну, он не был скомпилирован, потому что есть ошибка, которая блокирует компиляцию. Но я вижу, к чему вы клоните. Поскольку третий аргумент может быть любым вызываемым, мне казалось, и я думаю, что его аргумент может быть выведен из входных итераторов, но остальная часть его типа не могла. Однако это просто ограничение нашего понимания, потому что «clang» принимает его, и связанный Bugzilla подразумевает, что это действительный случай, страдающий от двусмысленности в парсере «g ++». –

+0

К сожалению, я имел в виду, что функция for_each уже скомпилирована. –

+1

Это, безусловно, выглядит как ошибка, ошибка ошибка: не может вызвать функцию-член 'void Foo :: print (const string &) const' без объекта подразумевает, что он правильно вывел тип параметра –

-4

Я не знаю почему. Но решение должно указать, какую печать он должен использовать: std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { this->print(x); });

С этим он компилируется. См.: http://coliru.stacked-crooked.com/a/1177b09a3e5863e2

+3

Это не ответ. Вопрос уже явно указывает, что добавление 'this->' делает этот компилятор. – lisyarus

+0

, а не http://stackoverflow.com/questions/11284059/call-method-inside-lambda-expression или http://stackoverflow.com/questions/4940259/lambdas-require-capturing-this-to-call- static-member-function – frank

+3

Это по-прежнему не имеет значения. Код в вопросе уже явно фиксирует «это». – lisyarus

5

Это документированный gcc bug, который по состоянию на август 2016 года еще не исправлен.