Rückwgabewert in Abhängigkeit von string literal?



  • Hallo,

    ist es mittels constexpr möglich den Rückgabewert einer Funktion in C++ zu verändern in Abhängigkeit eines übergebenen string literals?

    Also so:

    auto i = foo("sei_ein_int"); // i ist ein int
    auto d = foo("sei_ein_double"); // d ist ein double
    

    oder von mir aus auch so:

    constexpr compile_time_string str1 = "sei_ein_int";
    constexpr compile_time_string str2 = "sei_ein_double";
    auto i = foo(str1); // i ist ein int
    auto d = foo(str2); // d ist ein double
    

    Wobei compile_time_string halt eine entsprechende Wrapper-Klasse ist.

    Ich probier nämlich schon eine ganze Zeit jetzt herum und bekom das irgendwie nicht hin, da Funktionsparameter ja anscheinend keine constexpr sein können und ich diese deswegen nicht in std::conditional einsetzen kann...

    Daher: Geht das überhaupt prinzipiell oder ist das unmöglich?


  • Mod

    Das ist prinzipiell unmöglich. Was hast du vor? Warum denkst du, dies zu benötigen? Das klingt spontan nach einem umständlichen Eigenbau von Templates.



  • SeppJ schrieb:

    Das ist prinzipiell unmöglich.

    Mist, das hab ich befürchtet 😃

    SeppJ schrieb:

    Was hast du vor? Warum denkst du, dies zu benötigen? Das klingt spontan nach einem umständlichen Eigenbau von Templates.

    Ich hab eine Datenbank und mir schwebt sowas damit vor:

    auto val = db.read("int_lese_befehl"); // Vereinfacht, val ist jetzt ein int
    

    Dann könnte man sich das gecaste sparen. Außerdem wäre es schön wenn man einen Compile-Fehler bekommen würde wenn man einen ungültigen string übergibt (und nicht erst einen Fehler zur Laufzeit).

    Sowas hätte ich gerne. 🙂

    Mit templates geht das nicht, da die ja keine Zeichenketten können, daher kein Eigenbau selbiger...


  • Mod

    db.read<int>() ?



  • SeppJ schrieb:

    db.read<int>() ?

    Ok, so kann man das mit dem Rückgabewert machen, stimmt.

    Meine Frage war aber etwas falsch gestellt, es geht mir generell um das Problem mit strings als Übergabeparametern.

    Also bei einem read muss ich ja auch den Namen der Variablen angeben, also so:

    db.read<int>("my_int_value");
    

    Und das ist halt blöd, weil man sich da sehr leicht vertippen kann.

    Ich kann natürlich Variablen verwenden, wie z.B.:

    class Values
    {
        static const char MY_INT_VALUE[] = "my_int_value";
    };
    // ...
    
    db.read<int>(Values::MY_INT_VALUE);
    

    Problem, man kann nach wie vor "normale" Zeichenketten (also solche, die nicht in Values stehen) als Parameter übergeben.

    Am liebsten wäre mir etwas wie eine enum class , die kann man aber wieder nicht mit string Werten befüllen, und einen rießigen switch-case zu managen will ich auch unbedingt vermeiden...



  • happystudent schrieb:

    Also bei einem read muss ich ja auch den Namen der Variablen angeben, also so:

    db.read<int>("my_int_value");
    

    Und das ist halt blöd, weil man sich da sehr leicht vertippen kann.

    Du kannst dich überall vertippen, aber das was Seppj geschrieben hat "is the way to go".

    Wenn du Validierungn für den Namen der Variable machen willst musst Du es wohl oder übel selber parsen und auf Richtigkeit prüfen.

    Der andere wäre as_int, as_string Funktionen zu machen aber das ist so 80er und löst dein Problem auch nicht.



  • Ruvi schrieb:

    Du kannst dich überall vertippen, aber das was Seppj geschrieben hat "is the way to go".

    Nein, bzw. ja schon, aber dann bekomme ich auch einen Compile-Fehler. Wenn ich mich innerhalb eines strings vertippe bekomme ich keinen Compile-Fehler, das ist der entscheidende Unterschied.

    Ruvi schrieb:

    Wenn du Validierungn für den Namen der Variable machen willst musst Du es wohl oder übel selber parsen und auf Richtigkeit prüfen.

    Will ich ja. Nur geht das eben anscheinend nicht zur Compile-Zeit.

    Ruvi schrieb:

    ... und löst dein Problem auch nicht.

    eben.



  • Wieso nicht

    auto val = db.read<"my_int_value"_dbcmd>();
    

    oder sowas in der Art?



  • Das habe ich "mal schnell" hingeklatscht, aber es kommt mit einem ganzen Berg an Problemen. Vor allem bei komplexen SQL Querys, wenn man die zur compile time außeinanderpflücken will wirds abenteuerlich.

    Folgendes halte ich für den falschen Weg. Und vielleicht ein wenig am Ziel vorbei. Aber da ich die Zeit reingepackt hab, hier trotzdem:

    EDIT: Das ist nur ein Beispiel. Möglich wäre natürlich den String vorzuverarbeiten.

    #include "string.hpp"
    #include "string_algo.hpp"
    
    #include <iostream>
    
    MAKE_STRING(myStringInt, "int");
    MAKE_STRING(myStringFloat, "float"); // struct String { using data= std::tuple<char_<'f'>, char_<'l'>, ...> }
    
    template <typename StringT>
    struct A {
        static int call() { return 0; }
    };
    
    template <>
    struct A <myStringInt> {
        static int call() {
            return 2;
        }
    };
    
    template <>
    struct A <myStringFloat> {
        static float call() {
            return 2.3f;
        }
    };
    
    int main()
    {
        std::cout << A<myStringInt>::call() << std::endl;
        std::cout << A<myStringFloat>::call() << std::endl;
    
        // clunky, WIP
        std::cout << myStringFloat_ex::cstr << std::endl;
    }
    

    Ausgabe:

    2
    2.3
    float


  • Mod

    Soll das ein eigener SQL-Wrapper werden? Die gibt's doch schon wie Sand am Meer. Wenn man es dann doch unbedingt selber machen möchte, dann sollte doch die erste Station sein, sich mal anzusehen, wie die Konkurrenz gängige Probleme gelöst hat.



  • hustbaer schrieb:

    oder sowas in der Art?

    Hm, ist das nicht nur eine andere Schreibweise für eine constexpr Funktion? Muss aber zugeben dass ich mich mit eigenen Literalen noch nicht auskenne, werd ich mir mal genauer anschauen.

    5cript schrieb:

    Folgendes halte ich für den falschen Weg. Und vielleicht ein wenig am Ziel vorbei.

    Hm. Ok naja, trotzdem Danke 😃

    SeppJ schrieb:

    Soll das ein eigener SQL-Wrapper werden? Die gibt's doch schon wie Sand am Meer. Wenn man es dann doch unbedingt selber machen möchte, dann sollte doch die erste Station sein, sich mal anzusehen, wie die Konkurrenz gängige Probleme gelöst hat.

    Ja, also das ist eher ein selbst-gestelltes Übungsprojekt (um constexpr zu lernen). SQL Wrapper hab ich viele gefunden, aber keinen der die strings zur Compile-Zeit überprüft.


  • Mod

    happystudent schrieb:

    Ja, also das ist eher ein selbst-gestelltes Übungsprojekt (um constexpr zu lernen). SQL Wrapper hab ich viele gefunden, aber keinen der die strings zur Compile-Zeit überprüft.

    Das klingt ja auch nicht sehr sinnvoll und ich verstehe immer noch nicht, wozu das gut sein soll. Wenn das ein allgemeiner Wrapper sein soll, dann kann er keine vernünftige Prüfung durchführen, da er die Datenbankstruktur und den Willen des Nutzers nicht kennt. Wenn es um einen Wrapper um eine ganz spezielle Datenbank mit einer ganz speziellen Anwendung geht, dann stehen die Zugriffsmethoden doch sowieso fest und es macht keinen Sinn, Kommandos per Zeichenkette zu übergeben.


Log in to reply