'Get variable value from its name as a string at runtime in C++
I'm trying to reproduce (*) something similar to Python fstring, or at least its format function (and while at it, I'd like to implement something like its "Mini-language").
(*) N.B.: please note that I am aware of the existence of the standard lib's format library, as well as the existence of the {fmt} library; but,
a: neither the g++ (11.2.1) nor the clang++ (12.0.1) that I have on my machine can compile code including <format>, and
b: I don't want to use the excellent {fmt} lib, because I'm precisely trying to do my own thing/thingy.
I'm going to use a string in input to my format object, and any number of additional arguments, like that:
// First, some vars
std::string stef{"Stéphane"};
std::string cpp{"C++"};
int ilu3t{3000};
// Then the big deal
std::string my_fstring = badabwe::format(
"My name is {stef}, and I love {cpp} {ilu3t} !",
cpp,
stef,
ilu3t
);
// Obviously, only the 1st parameter is positional!
// my_fstring should now be:
// My name is Stephane, and I love C++ 3000 !
That's one of the first problem, I have to solve. I think this process is called reflection (please let me know if it's the case).
Next I need to handle a variable number of arguments; the 1st parameter is the only positional and mandatory one (I'm still trying to find a way to iterate over a parameter pack), but its a subject for another question.
Solution 1:[1]
A function is not aware of name of parameters passed it. The parameter doen't even have to have a name:
void foo(int x); // name of the argument is x
foo(42); // 42 has no name
As suggested in a comment, if you want some mapping between strings (values to be replaced) and strings (their names) then you can use a map. To avoid the caller to spell out this mapping you can use a macro (usually to be avoided, but for now its the only way to get the name of a variable as a string):
#include <iostream>
#include <string>
#include <unordered_map>
using token_t = std::unordered_map<std::string,std::string>;
std::string format(const std::string& tokenized,const token_t& token) {
return "test";
}
#define tokenize(token) { #token , to_string(token) }
using std::to_string;
std::string to_string(const std::string& str) { return str; }
int main() {
std::string stef{"Stéphane"};
std::string cpp{"C++"};
int ilu3t{3000};
std::string my_fstring = format(
"My name is {stef}, and I love {cpp} {ilu3t} !",
{
tokenize(cpp),
tokenize(stef),
tokenize(ilu3t)
}
);
}
I assumed that you can use std::to_string, though there is no std::to_string(const std::string&) hence I added a custom implementation.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
