2013-03-23 21 views
5

Chciałbym mieć domyślny funktor dla parametru functor w konstruktorze klasy. Jako minimalny przykład wymyśliłem klasę, która powinna służyć jako filtr, który filtruje elementy typu T iif funkcja filtru zwraca true. Funkcja Filtr powinien być dostarczony w konstruktorze, zalegających na „Akceptuj wszystkie” funkcje filtra:Funkcja Lambda jako domyślny argument dla funkcji std :: in Konstruktor

template<class T> 
class Filter 
{ 
public: 
    typedef std::function<bool(const T&)> FilterFunc; 

    Filter(const FilterFunc & f = [](const T&){ return true; }) : 
     f(f) 
    { 
    } 

private: 
    FilterFunc f; 
}; 

I instancji klasy szablonu tak:

int main() { 
    Filter<int> someInstance; // No filter function provided (<-- line 19) 
} 

jednak gcc 4.7 doesn't seem to like this piece of code:

prog.cpp: In constructor ‘Filter<T>::Filter(const FilterFunc&) [with T = int; Filter<T>::FilterFunc = std::function<bool(const int&)>]’: 
prog.cpp:19:17: internal compiler error: in tsubst_copy, at cp/pt.c:12141 
Please submit a full bug report, 
with preprocessed source if appropriate. 
See <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions. 
Preprocessed source stored into /home/g9i3n9/cc82xcqE.out file, please attach this to your bugreport. 

Co jest nie tak? Czy mój kod jest zgodny ze standardem (więc GCC jest tutaj naprawdę błędny lub nie zaimplementował tego) lub czy robię coś nie tak?

Jako obejście, Używam obecnie domyślnie skonstruowany std::function i tylko nazwać (gdzie chcę go nazwać), jeśli został ustawiony:

Filter(const FilterFunc & f = FilterFunc) : 
     f(f) 
    { 
    } 

    // When using it: 
    void process() { 
     if (!f || f(someItem)) { // <-- workaround 
     } 
    } 
+0

Wydaje się błąd. Ponad 4,8 kompiluje dobrze: http://liveworkspace.org/code/TFMDc$0 – SomeWittyUsername

+0

Działa również z Clang 3.2. – ipc

+0

Dziękujemy za testowanie innych kompilatorów. Dodałem obejście tego problemu, które jest dopuszczalne tylko w niektórych przypadkach, takich jak moje, ale mogą istnieć inne przypadki, w których nie można tego użyć. – leemes

Odpowiedz

3

Jest to błąd: kompilator awarii lub wystąpił krytyczny błąd wewnętrzny podczas przetwarzania kodu źródłowego, a sam komunikat zachęca do potraktowania błędu jako takiego:

"Proszę przesłać pełny raport o błędzie, w razie potrzeby z wstępnie przetworzonym źródłem."

Oto kolejny możliwe obejście:

template<class T> 
class Filter 
{ 
public: 
    typedef std::function<bool(const T&)> FilterFunc; 

    Filter() { } 
    Filter(FilterFunc const& f) : f(f) { } 

private: 
    FilterFunc f = [](const T&){ return true; }; 
}; 

Jako kolejna alternatywa, GCC obsługuje delegowanie konstruktorów, która może warto rozważyć:

#include <functional> 

template<class T> 
class Filter 
{ 
public: 
    typedef std::function<bool(const T&)> FilterFunc; 

    Filter() : Filter([](const T&){ return true; }) { } 
    Filter(FilterFunc const& f) : f(f) { } 

private: 
    FilterFunc f; 
}; 
+1

Dziękujemy za alternatywne rozwiązanie. W odniesieniu do błędu: ja jako użytkownik nie wiem, czy błąd był, ponieważ mój kod był błędny i komunikat o błędzie nie mógł zostać wygenerowany (moja wina) lub jeśli mój kod był OK i kompilator nie skompilował go (jego wina) . Oczywiście ten drugi przypadek jest w 99% prawdopodobny. ;) Ale ponieważ nie jestem doskonały, najpierw szukam błędów w moim kodzie. – leemes

+0

@leemes: To zdecydowanie nie jest twój kod w tym przypadku. Nie ma w tym nic złego;) –

+0

@musi pierwszy przypadek to także błąd kompilatora – SomeWittyUsername

Powiązane problemy