Ich versuche eine Template-Funktion zu erstellen, die eine iterable und eine Funktion akzeptiert, so dass die übergebene Funktion implizit an eine std::function
übergeben wird des entsprechenden Typs (so dass es sowohl mit vollen Funktionen als auch mit lambdas verwendet werden kann).(g ++ 4.7.1) Ersetzen von expliziten Typnamen durch eine äquivalente Klasse typedef kann nicht kompiliert werden
Hier ist der Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <typeinfo>
template<typename T>
void bar(const T & base, std::function<bool(int)> f) // works
//void bar(const T & base, std::function<bool(typename T::iterator::value_type)> f) // fails to compile
{
std::cout << ((typeid(std::function<bool(int)>) == typeid(std::function<bool(typename T::iterator::value_type)>))?"identical":"distinct") << std::endl;
}
bool filter(int x) { return x%2==0; }
int main() { bar(std::vector<int> {0, 1}, filter); }
Zusammengestellt mit g++-4.7 -std=c++11 -o itest itest.cpp
dies erzeugt identical
.
Wenn Sie uncomment Linie 10 und Kommentarzeile 9 und wie oben kompilieren, schlägt stattdessen Kompilation mit
g++-4.7 -std=c++11 -Wall -Werror -o itest itest.cpp
itest.cpp: In function 'int main()':
itest.cpp:16:53: error: no matching function for call to 'bar(std::vector<int>, bool (&)(int))'
itest.cpp:16:53: note: candidate is:
itest.cpp:9:10: note: template<class T> void bar(const T&, std::function<bool(typename T::iterator::value_type)>)
itest.cpp:9:10: note: template argument deduction/substitution failed:
itest.cpp:16:53: note: mismatched types 'std::function<bool(typename T::iterator::value_type)>' and 'bool (*)(int)'
Ich sollte anmerken, dass die unveränderte Version mit Xcode erfolgreich ist (die entsprechenden Optionen festgelegt haben), aber ich d bleibe lieber mit g ++ über Klängen wenn möglich. Mache ich etwas falsch oder ist das ein bekannter Fehler in g ++?
Huh, danke. Ich habe eine andere (ziemlich schreckliche) Problemumgehung implementiert, die nicht erfordert, dass der Aufrufer sich jemals auf den zweiten Typ bezieht oder diesen ableitet. – Bakkot
Hoppla, vergiss die [link] (https://gist.github.com/a172651b93dc4670f295). Für Leute, die nicht beide lesen wollen, ist es im Wesentlichen currying. – Bakkot