Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Funktions-Template nur mit dem Rückgabetyp spezialisieren

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
30.01.2013, 14:02 Uhr
ao

(Operator)


Hallo zusammen, ich hab ne Frage zu Funktions-Templates.

Ich habe einen einfachen Datenspeicher:

C++:
class DataStorage
{
  //  Eine Liste von Name-Wert-Paaren.
  //  Beispielhafter Inhalt:
  //  X-START=0.0
  //  X-DELTA=0.1
  //  NUM-SAMPLES=1000
  std::unordered_map<std::string, std::string> nameValuePairs;

public:
  //  Funktion, um zu einem Namen den Wert zu holen, und zwar
  //  gleich als Zahlenwert im passenden Datentyp.
  //  Für RT kommen nur Trivialtypen in Frage (int, double, ...)  
    template <typename RT>
    RT GetValue    (const std::string & name)
    {
        std::stringstream ss (nameValuePairs[name]);
        RT value;
        ss >> value;
        return value;
    }
};


Geplante Verwendung:

C++:
int main ()
{
  DataStorage storage;
  
  //  Hier Storage mit Daten füllen
  
  //  Abfragen:
  double xDelta = storage.GetValue ("X-DELTA");
  int numSamples = storage.GetValue ("NUM-SAMPLES");
}


Problem: Mein Compiler (zur Zeit Visual Studio 2010, demnächst auch gcc) kann das Template nicht nur anhand des Rückgabetypes spezialisieren.

Etwas unschöner Workaround: Dem Compiler mit einem Dummy-Parameter auf die Sprünge helfen: Indem ich eine Variable oder auch ein Literal vom entsprechenden Typ hineinstecke, weiß der Compiler, was ich mit RT meine.

C++:
    template <typename RT>
    RT GetValue    (RT specifyType, const std::string & name)
    {
        std::stringstream ss (nameValuePairs[name]);
        RT value;
        ss >> value;
        return value;
    }

  double xDelta = storage.GetValue (1.0, "X-DELTA");
  int numSamples = storage.GetValue (1, "NUM-SAMPLES");


Gibts auch einen "richtigen" Weg dafür?

Vielen Dank!

Dieser Post wurde am 30.01.2013 um 14:37 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
30.01.2013, 14:39 Uhr
TOSHMAX



Wenn der Compiler den Parameter nicht selbst ermitteln kann, ist es auch möglich ihm Den beim Aufruf zu übergeben:

C++:
  double xDelta = storage.GetValue<double> ("X-DELTA");
  int numSamples = storage.GetValue<int> ("NUM-SAMPLES");


Eine andere Möglichkeit wäre auch noch, bei GetValue einen eigenen Wrapper zurückzugeben, der nur den String übergeben bekommt. Aus diesem heraus wird dann z. B. mit 'operator double()' (oder gleich einem operator T() als Template) der korrekte Wert geparst.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
30.01.2013, 16:22 Uhr
Tommix



Hallo,
ich fürchte fast, das geht by design nicht. Der Rückgabetyp gehört nicht zur Signatur, auch könnte etwas wie

C++:
std::cout << storage.GetValue();


nicht aufgelöst werden. Letztlich sind auch Von-Hand-Überladungen wie

C++:
int foo(string name);
double foo(string name);


nicht möglich.

Gruß, Tommix

(An der Stelle bringt dann meist wer den Beweis, dass ich mich irre.)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
31.01.2013, 09:01 Uhr
ao

(Operator)


@Tommix: Ja, das hab ich gemerkt, dass es so nicht geht

@TOSHMAX: Die Idee mit der Wrapperklasse und dem operator T probiere ich mal.

Der Sinn von dem Ganzen soll sein, dass ich mich auf der rechten Seite vom Gleich-Zeichen nicht drum kümmern will, in welchen Typ die Daten konvertiert werden müssen. Zumindest nicht so, dass ich links und rechts von Hand konsistent halten muss. In Wirklichkeit sind das nämlich viel mehr Parameter als nur die drei aus dem Beispiel.

Deshalb sind sowohl mein Workaround als auch der Vorschlag mit dem Template-Argument nicht die Ideallösung.

Danke euch beiden.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
31.01.2013, 15:42 Uhr
Tommix



Wäre vielleicht das ein Ansatz?

C++:
template <typename RT>
    void GetValue    (RT& returnValue, const std::string & name)
    {
        std::stringstream ss (nameValuePairs[name]);
        ss >> returnValue;
    }



- Tommix
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: