2016-06-30 7 views
0

Ich versuche, eine std::unique_ptr Funktors in std Algorithmen zu verwenden, aber wenn ich es verwenden, wie folgt aus:Begriff muß nicht auf 1 Argument in std Algorithmus zu bewerten, wenn einstellige op Verwendung mit std :: definiert unique_ptr

std::unique_ptr<IFormatter> format(new formatter("abcd")); 
std::transform(vec.begin(), vec.end(), vec.begin(), *format.get()) 

Ich bin Kompilierungsfehler wird angezeigt:

Fehler 1 Fehler C2064: Begriff wird nicht zu einer Funktion ausgewertet, die 1 Argumente nimmt.

komplettes Programm unter:

#include <iostream> 
#include <string> 
#include<algorithm> 
#include<vector> 

using namespace std; 

struct IFormatter 
{ 
protected: 
    std::string keyFormat; 
    void fun(std::string& str) 
    { 
     // do something here. 
    } 
public: 
    IFormatter(std::string keyFormat) : keyFormat(keyFormat) {} 
    virtual std::string operator() (const std::string &key) = 0; 
}; 

struct formatter : IFormatter 
{ 
    formatter(std::string keyFormat) : IFormatter(keyFormat) {} 
    std::string operator() (const std::string &key) 
    { 
      std::string s = keyFormat; 
      fun(s); 
      return s; 
    } 
}; 

int main() 
{   
    std::vector<std::string> vec{ "one", "two" }; 
    std::unique_ptr<IFormatter> format(new formatter("$ID$")); 
    // This line compiles fine if i define format as - formatter format("abcd"); 
    std::transform(vec.begin(), vec.end(), vec.begin(), format.get()); 
    start s; 
    return 0; 
} 

EDIT: Vielen Dank an Alle für die Vorschläge aber format.get() war ein Tippfehler, wurde mit I * format.get() & i mit * Format versucht hatte, (Ich stimme zu, dass get() nicht wirklich benötigt wird.). Die Verwendung von std :: ref (* format) löst das Problem nicht. Das ist seltsam, aber ich bekomme immer noch denselben Fehler.

P.S. WENN es wichtig ist, verwende ich Visual Studio 2013.

+1

Schnell Vermutung: versuchen '* format.get()'. Ein Zeiger auf einen 'Formatierer' ist nicht aufrufbar. Ein Verweis auf einen 'Formatierer' * ist * aufrufbar. – BoBTFish

+1

@BoBTFish: '.get()' wird nicht benötigt, '* format' ist genug und mehr idiomatisch. – Jarod42

Antwort

6
std::transform(vec.begin(), vec.end(), vec.begin(), std::ref(*format)); 

Ein Zeiger ist nicht aufrufbar. Aber Sie haben einen Zeiger auf die Basis, so std::ref zu vermeiden, schneiden.


Seit MSVC 2013 des reference_wrapperhates abstract classes, verwenden Sie einen Lambda:

std::transform(vec.begin(), vec.end(), vec.begin(), 
       [&](const std::string& s) { return (*format)(s); }); 
+0

Danke für das Erwähnen von Slicing. Ich hatte diesen Teil verpasst. aber das ursprüngliche Problem ist immer noch wie es ist. – user888270

+0

@ user888270 Ah, [MSVC-Fehler] (https://connect.microsoft.com/VisualStudio/feedback/details/828696). –

Verwandte Themen