Estoy tratando de crear una función de plantilla que acepte un iterable y una función, de modo que la función pasada se convertirá implícitamente en std::function
del tipo apropiado (lo que permite su uso tanto con funciones completas como con lambdas).(g ++ 4.7.1) Reemplazar el nombre de tipo explícito con una clase equivalente typedef no puede compilar
Aquí está el código:
#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); }
compilado con g++-4.7 -std=c++11 -o itest itest.cpp
esto produce identical
.
Si la línea 10 y la línea de comentario uncomment 9 y compilar que el anterior, en vez de compilación falla con
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)'
Debo señalar que la versión no modificada tiene éxito con Xcode (habiendo establecido las opciones apropiadas), pero me prefiero seguir con g ++ sobre clang si es posible. ¿Estoy haciendo algo mal, o se trata de un error conocido en g ++?
Huh, gracias. Implementé otra (bastante terrible) solución, una que no requiere que la persona que llama se refiera ni obtenga el segundo tipo. – Bakkot
Vaya, olvidé el [enlace] (https://gist.github.com/a172651b93dc4670f295). Para las personas que no quieren leerlo, es básicamente currying. – Bakkot