5 Stimmen

C++ Template-Programmierung - Abgelehnte Funktionsaufrufe

Ich suche nach einer eleganten Lösung für das folgende Problem. Ich habe eine Task-Struktur, die ich für verzögerte Funktionsaufrufe verwende.

template  struct Task1
{
    T Arg1;
    Delegate TaskDelegate;
};

Das Problem, das ich habe, ist folgendes:

Task1 MyTask;

Das führt dazu, dass der Parameter als Konstante Referenz gehalten wird. Weiß jemand eine gute Lösung, um dieses Problem zu umgehen? Ich könnte Regeln durchsetzen, dass die Delegat-Signatur immer const&-Parameter annimmt, aber das scheint restriktiv zu sein. Ich könnte immer zwei Task-Strukturen haben (eine für Verweis und eine für Wert), aber das scheint hässlich zu sein.

Die andere Lösung wäre, das folgende zu erstellen:

template  struct Task1
{
    T2 Arg1;
    Delegate TaskDelegate;
};

Gibt es einen Weg, T2 standardmäßig auf denselben Typ wie T1 zu setzen? Auf diese Weise brauche ich jedes Mal, wenn ich eine Methodenwertsignatur habe, keine zusätzlichen Vorlagenparameter.

EDIT: Die Vorlage wird für einen mehrfädigen Task-Scheduler verwendet. Hier ist ein Beispiel:

void MyClass::Populate(const std::string& instrText);

CTaskScheduler::Schedule(Task1(this, &MyClass::Popluate, "MeinString"));

9voto

Sie könnten sich die Implementierung der function<> entweder in boost oder im bevorstehenden Standard ansehen. Tatsächlich können Sie einfach use function<>. Ich glaube, die Lösung dort bestand darin (vor C++0x), immer eine Kopie der Argumente zu speichern, wenn der Benutzer Referenzsemantik möchte, kann er einen Referenzwrapper verwenden.

Was den Zugriff auf einen Wert betrifft, können Sie sich einige einfache Metafunktionen ansehen, um const oder & zu entfernen:

// Remove reference:
template 
struct remove_reference {
   typedef T type;
};
template 
struct remove_reference {
   typedef T type;
};

Gleiches gilt für const.

2voto

Diego Sevilla Punkte 27639

Sie können die boost.type_traits Bibliothek verwenden, um die Konstanz des Parameters mit boost::remove_const zu entfernen.

2voto

rcollyer Punkte 10285

Zusätzlich zu boost::type_traits gibt es eine boos::call_traits Bibliothek, die speziell dafür entwickelt wurde, Probleme wie dieses zu behandeln. Sie bietet auch Mechanismen, um das Problem mit Referenzen von Referenzen zu vermeiden.

1voto

Karel Petranek Punkte 14845

boost::remove_const sollte Ihnen in diesem Fall helfen:

template  struct Task1
{
    typename boost::remove_const::type Arg1;
    Delegate TaskDelegate;
};

Alternativ können Sie boost vermeiden, wenn Sie die Vorlagen-Spezialisierung für konstante Typen verwenden:

template  struct Task1
{
    T Arg1;
    Delegate TaskDelegate;
};

template  struct Task1
{
    T Arg1;
    Delegate TaskDelegate;
};

(Warnung: nicht getestet)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X