2016-08-09 186 views
0

Warum diese 5.3.1 in G ++ kompiliert wird fehlschlagen (mit --std = C++ 1J):const in std :: Funktion Template-Parameter

#include <iostream> 
#include <vector> 
#include <functional> 

using std::cout; 
using std::endl; 

template<typename InputIterator> 
void foo(InputIterator i, std::function<bool(typename const std::iterator_traits<InputIterator>::value_type&)> f) 
{ 
    cout << f(*i) << endl; 
} 

int main() { 
    std::vector<int> v { 1,2,3 }; 
    foo(v.begin(), [] (const int& a) -> bool { return false; }); 
} 

Dies schlägt mit der Nachricht:

g++ -std=c++1y -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"source.d" -MT"source.o" -o "source.o" "../source.cc" 
../source.cc:16:110: error: template argument 1 is invalid 
void foo(InputIterator i, std::function<bool(typename const std::iterator_traits<InputIterator>::value_type&)> f) 
                              ^
../source.cc:16:110: error: template argument 1 is invalid 
../source.cc:16:110: error: template argument 1 is invalid 
../source.cc:16:110: error: template argument 1 is invalid 
../source.cc:16:110: error: template argument 1 is invalid 
../source.cc:16:32: error: ‘std::function’ is not a type 
void foo(InputIterator i, std::function<bool(typename const std::iterator_traits<InputIterator>::value_type&)> f) 
           ^
../source.cc:16:40: error: expected ‘,’ or ‘...’ before ‘<’ token 
void foo(InputIterator i, std::function<bool(typename const std::iterator_traits<InputIterator>::value_type&)> f) 
             ^
../source.cc: In function ‘int main()’: 
../source.cc:23:61: error: no matching function for call to ‘foo(std::vector<int>::iterator, main()::<lambda(const int&)>)’ 
    foo(v.begin(), [] (const int& a) -> bool { return false; }); 
                  ^
../source.cc:16:6: note: candidate: template<class InputIterator> void foo(InputIterator, int) 
void foo(InputIterator i, std::function<bool(typename const std::iterator_traits<InputIterator>::value_type&)> f) 
    ^
../source.cc:16:6: note: template argument deduction/substitution failed: 
../source.cc:23:61: note: cannot convert ‘<lambda closure object>main()::<lambda(const int&)>{}’ (type ‘main()::<lambda(const int&)>’) to type ‘int’ 
    foo(v.begin(), [] (const int& a) -> bool { return false; }); 
                  ^

(Beachten Sie, dass Zeilennummern wegen einiger Header-Kommentare, die ich weggelassen habe, um 8 deaktiviert sind).

Aber wenn ich alle const Qualifier entfernen, dann kompiliert es gut.

+1

'const' und' typename' sollte umgekehrt sein; Oder, verschieben Sie 'const 'nach" value_type "und vor dem kaufmännischen Und-Zeichen nach rechts. 'typenname std :: iterator_traits :: value_type' ist der Name des Typs, den Sie ändern. Sie müssen alle Teile zusammenhalten. –

Antwort

2

Ich glaube, Sie wollen const typename ... statt typename const ... :)

+0

Und dies, weil z.B. 'const int *' und 'int * const 'sind zwei sehr unterschiedliche Typen. – rubenvb

+0

@rubenvb In diesem Fall ist es mehr wie 'const unsigned int' ist ein gültiger Typ, aber' unsigned const int' ist syntaktischer Unsinn. –

+0

@Igor Ah ja ich sehe jetzt, du hast Recht. – rubenvb