2016-04-22 16 views
0

Wie ist es möglich, eine Templat Funktionen mit dem STL versehen Algorithmen in <algorithm> zu benutzen? Zum Beispiel dieser Code nicht kompilieren, weil Compiler Template-Parameter für die predicate Funktion ableiten kann:STL-Algorithmen mit Templat-Funktionen als Parameter

#include <iostream> 
#include <algorithm> 

template< typename CharType > 
bool predicate(const CharType& c) 
{ 
    return c == '0'; 
} 

std::string 
process_string(const std::string& str) 
{ 
    std::string result; 
    std::copy_if(str.begin(), 
        str.end(), 
        std::back_inserter(result), 
        predicate); 
    return result; 
} 

int main() 
{ 
    std::cout << process_string("AK0NNDK0ASDAS0") << std::endl; 
    return 0; 
} 

Antwort

5

Sie bieten können den Typ: predicate<std::string::value_type>

0

Verwendung static_cast Überlastung Problem zu beheben:

std::copy_if(str.begin(), 
       str.end(), 
       std::back_inserter(result), 
       static_cast<bool (*)(const char&)>(predicate)); 
6

Mehrere Möglichkeiten: einschließlich

  • bieten dem Typ explizit

    predicate<std::string::value_type> 
    
  • Verwendung Lambda

    [](auto&&e) { predicate(e); } 
    
+0

'auto &&' ist generischer, aber in diesem speziellen Fall nicht erforderlich. – Yakk

+1

Leider funktioniert der Lambda-Code nicht in C++ 11, die ein Tag in der Frage ist. Generische Lambdas funktionieren ab C++ 14. – stefaanv

1

Eine Vorlage selbst kein Funktionsargument sein kann. In diesem Fall sollten Sie einen Funktionszeiger auf die Vorlage Funktion zu übergeben, die Sie instanziieren müssen als predicate<char>:

std::copy_if(str.begin(), 
       str.end(), 
       std::back_inserter(result), 
       predicate<char>); 
1

eines instanziierten Funktors Verwenden Sie w/a Templat-operator():

namespace detail { 

struct predicateFunctor { 
    template<typename CharType> 
    bool operator()(const CharType& c) 
    { 
     return c == '0'; 
    } 
}; 

} /*namespace detail*/ 

static auto predicate = detail::predicateFunctor{}; 

std::string process_string(const std::string& str) 
{ 
    std::string result; 
    std::copy_if(str.begin(), str.end(), std::back_inserter(result), predicate); 
    return result; 
} 


int main() 
{ 
    std::cout << process_string("AK0NNDK0ASDAS0") << std::endl; 
    return 0; 
} 

Demo