2013-04-15 1 views
3

Следующий код не скомпилирован в gcc 4.6.3, в то время как он компилируется безупречно в clang 3.1 (я предоставляю две версии класса DummyMath, обе имеют ту же проблему):Ошибка компиляции GCC при использовании метода класса шаблона внутри выражения лямбда

#include <iostream> 
using namespace std; 

//* // To swap versions, comment the first slash. 

// =============================================== 
// V1 
// =============================================== 
template <typename T> 
class DummyMath 
{ 
public: 
    T sum(T a1, T a2); 
    T mult(T a1, int n); 
}; 

template <typename T> 
T DummyMath<T>::sum(T a1, T a2) 
{ 
    return a1 + a2; 
} 

template <typename T> 
T DummyMath<T>::mult(T a1, int n) 
{ 
    auto x2 = [this](T a1) -> T 
    { 
     return sum(a1, a1); // <------- gcc will say that "sum" was not declared in this scope! 
    }; 

    T result = 0; 
    n = n/2; 
    for(int i = 0; i < n; ++i) 
     result += x2(a1); 
    return result; 
} 
/*/ 
// =============================================== 
// V2 
// =============================================== 
template <typename T> 
class DummyMath 
{ 
public: 
    T sum(T a1, T a2) 
    { 
     return a1 + a2; 
    } 

    T mult(T a1, int n) 
    { 
     auto x2 = [this](T a1) -> T { 
      return sum(a1, a1); 
     }; 

     T result = 0; 
     n = n/2; 
     for(int i = 0; i < n; ++i) 
      result += x2(a1); 
     return result; 
    } 
}; 
//*/ 

int main() 
{ 
    DummyMath<float> math; 
    cout << math.mult(2.f, 4) << endl; 

    return 0; 
} 

ошибка:

main.cpp:25:20: error: ‘sum’ was not declared in this scope 

Обе версии (V1 и V2) класс DummyMath неудачи в GCC, и оба успех в звоне. Это ошибка в GCC?

Спасибо.

+1

Если вы переписываете его как нечто вроде 'return DummyMath :: sum (a1, a1);' это работает? – Patashu

+0

Действительно, это работает сэр. – Monfico

+2

В gcc4.7.2 есть внутренняя ошибка компилятора, что, безусловно, является ошибкой. Так что, вероятно, ошибка в 4.6.3 тоже. –

ответ

4

Это известная ошибка из gcc 4.7.2 (см. Это question). Компилятор распознает, что этот указатель должен быть захвачен, а сгенерированное закрытие содержит указатель для него, но этот указатель не инициализируется в конструкторе закрытия.

Вы можете использовать return this->sum(a1, a2);, чтобы заставить его работать. Выполнение вашего примера на LiveWorkSpace показывает, что это исправлено для gcc> = 4.7.3, а также Clang 3.2 и Intel 13.0.1 (т. Е. Печать 8 в качестве вывода).

Поддержка C++ 11 очень полезна, и лучше всего перейти к последней версии вашего любимого компилятора как можно скорее. К сожалению, большинство дистрибутивов Linux поставляют упакованные версии gcc 4.7.2 и еще не для gcc 4.8.0. Возможно, вам придется скомпилировать их из источника.

+1

gcc 5.4 также имеет эту ошибку. Однако предлагаемое исправление решает. Спасибо! –