C++ Wie auf Vorgefertigte Funktionen, die mit std::bind / std::function
Wenn Sie eine vorgefertigte Klasse oder eine Vorlagen-Funktion (oder Kombination aus beiden), wie binden Sie diese Funktion, (die Erhaltung der template-parameter type)?
Bekam ich etwas Hilfe, um die grundlegende syntax in einem post weiter unten zu binden, um Funktionen mit expliziten template-type-Parameter, verlieren aber die Fähigkeit, template type Parameter in den Prozess.
Ist es möglich, diese so zu arbeiten, dass es noch möglich ist, eine Vorlage-Typ-Parameter mit Zukunft ruft?
Gereinigt bis dieser code viel, aber es wird offensichtlich nicht kompilieren, weil ich nicht finden können, die richtige syntax (gibt es irgendwelche Möglichkeiten, dies zu tun)?
Entfernt die "vector" - Anforderung zu vereinfachen:
Danke für die Hilfe!
#include <functional>
#include <vector>
#include <string>
/***************************************/
template <typename CommandTemplateType>
class Storage
{
public:
//No idea how to define this vector to allow Template Parameters
//static std::vector<std::function<void<ParameterTemplateType>
// (std::shared_ptr<ParameterTemplateType>)>> Functions;
//I really don't need the collection, a single member would kick start my research:
static std::function<void<ParameterTemplateType>(std::shared_ptr<ParameterTemplateType>)> Function;
template <typename ParameterTemplateType>
static void Execute(ParameterTemplateType parameter)
{
//Look up index, or loop through all..
//I am trying to invoke the bound function with a template param:
//Functions[index]<ParameterTemplateType>(parameter);
//preferably, just:
Function<ParameterTempalteType>(parameter);
}
};
/***************************************/
template <typename TemplateType>
class MyClass
{
template <typename ParameterTemplateType>
void MyFunction(ParameterTemplateType myParameter)
{
//Do something;
}
MyClass()
{
std::string parameter = L"Test String";
//Do not know how to include the
//template<typename ParameterTemplateType> definition to bind call.
//Storage::Functions.push_back(
// std::bind(&MyClass::MyFunction<ParameterTemplateType>,
// this, std::placeholders::_1));
//Or just something like:
Storage::Function = std::bind(&MyClass::MyFunction<ParameterTemplateType>,
this, std::placeholders::_1));
/***************************************/
//Call the bound function with an explicit parameter somehow:
std::string parameter = L"Test String";
Storage::Execute<std::string>(parameter);
}
};
- Was wollen Sie übergeben werden, als
myParameter
? - Anmerkung zur Terminologie: es gibt keine solche Sache wie eine "vorgefertigte Klasse/Funktion". Es gibt Klassen-templates und Funktions-templates. Das ist ein ganz fundamentaler Unterschied: es ist nicht so, dass etwas (eine "Vorlage", was immer das ist) wird auf eine Klasse angewendet. Es ist Umgekehrt: eine Klasse Vorlage selbst ist eine Vorlage, ein Modell oder eine Form, aus dem erstellen einer konkreten Klasse (durch einfügen von template-Argumente). Denken Sie an eine Klasse Vorlage, wie ein Schimmel, von dem aus ein Schwert (= Klasse), nicht wie ein Schwert, mit einigen Verzierungen auf Sie.
- Wenn ich verstehe, was du fragst richtig, es ist unmöglich. std::bind ist ein run-time-Konzept, Rückgabe von (im wesentlichen) eine Funktion, die aufgerufen werden können. Die Instanziierung einer Funktion Vorlage (ausfüllen der Vorlage-parameter) werden muss, geschieht bei der Kompilierung. Sie kann nicht laufen-Zeit binden, um eine Funktion, die (möglicherweise) noch kompiliert werden müssen...
- Ich fand heraus, wie es zu tun. Sie haben, um wickeln Sie die Vorlagen-Funktion in eine vorgefertigte container von einer Art sein. Habe ich geschrieben, die Antwort unten. Vielen Dank an alle für all die Hilfe!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der zentralen Themen ist, die in C++11 kann man nicht tun, sowas wie:
Klassen und Funktionen sind vorgefertigte, aber nicht die Eigenschaften.
Die "Magie" ist:
Können Sie Binden Sie dann eine Vorlagen-Funktion um diese Funktion wie:
Und Sie aufrufen können all dies und bieten eine vorgefertigte parameter "type" wie folgt:
parameter->get() = "Hello World".
was macht das?Den template-argument für
std::function
sollte die Signatur der Funktion nach template-type substitution durchgeführt wurde. In Ihrem Fall, wederTemplateType
nochFunctionTemplateType
haben einen Effekt auf die Signatur der MemberfunktionMyFunction
- es wird immer wieder einstd::string
und nehmen Sie ein einzelnesstd::string
argument. Daher diestd::function
Sie gehen, um Geschäft in Ihrerstd::vector
werden sollte:Daran erinnern, dass eine Elementfunktion hat einen impliziten ersten argument
this
. Sie zu binden, müssen Sie das erste argument desMyClass<...>::MyFunc<...>
zu dem Objekt, das Sie aufrufen möchten, auf. Vermutlich, da man bindet die Funktion inMyClass
's Konstruktor, der Sie das Objekt haben möchten, dassMyClass
Instanz. Das bedeutet, dass Ihrepush_back
sollte wie folgt Aussehen:Nun die Funktion, die geschoben wird, ist in
Functions
gebunden ist, um IhreMyClass
Objekt und übernimmt ein einzelnes argument des Typsstd::string
. Ruft man diese Funktionen so auf:&
("Adresse") gibt man ein Zeiger auf member-Funktion, die ähnlich wie ein Funktions-pointer, aber die Funktion, die Punkte müssen genannt werden, die auf ein bestimmtes Objekt. Member-Funktionen werden immer für ein Objekt aufgerufen, es sei denn, Sie sind statisch.bind
tun, um diese Funktion? Alle Argumente nach dem Zeiger auf member-Funktion sind Argumente, sollte bound, um die Argumente dieser Funktion. IhreMyFunction
hat zwei Argumente: das erste ist die implizitethis
argument, dass jedes Mitglied-Funktion hat, und die zweite ist diestd::string
. So binden wir das aktuelle Objektthis
dem ersten argument und, indem Sie einen Platzhalter verwenden, sagen wir das andere argument (diestd::string
sollte ungebunden. Nun die Funktion, dassbind
gibt nur ein argument, dasstd::string
.<anything>
gab ich in meiner Antwort. Deine ursprüngliche Frage hatte einenFunctionTemplateType
hatte keine Auswirkungen auf irgendetwas. Ich war nur zu sagen, Sie könnten jede Art für sich, dass -anything
ist nicht etwas bestimmtes. Könnte es seinint
,Foo
, was auch immer.Wenn ich Sie richtig verstanden... 🙂
Was Sie tun möchten ist nicht möglich, da für template<class T> void foo(T) - Funktionen foo<int>() und foo<double> sind von verschiedenen Arten und Sie können nicht erstellen Sie Vektor-holding Zeiger auf Funktionen, die direkt durch Vektor homogene container.
Zu überwinden, können wir die Verwendung von boost::variant<> entweder speichern von Pointern, die verschiedenen Arten von Funktionen oder zum speichern von Argumenten von Funktionen.
Leider, in jedem Fall müssen Sie instanziieren Funktion Vorlagen, bevor Sie Sie in container, weil C++ nicht machen kann, code-Generierung on-the-fly. Ich denke, dass es möglich ist, dass Sie wissen, alle möglichen Arten von Argumenten, die Funktion kann verwendet werden, so dass möglicherweise nicht ein problem.
MyClass c-tor-weiß nicht, nichts über
FunctionTemplateType
deshalb kann es push_back nur explizite spezialisiert (sorry, es ist ein Ausdruck von mir... ich weiß nicht den richtigen Begriff), wie Sie in dieserliveworkspace link