我正在尝试复制(*(类似于Pythonfstring
的东西,或者至少是它的format
函数(在这方面,我想实现一些类似于它的"迷你语言"的东西(。
(*(N.B.:请注意,我知道标准库的格式库的存在,以及{fmt}库的存在;但是,
a:/strong>我机器上的g++(11.2.1(和clang++(12.0.1(都不能编译包括<format>
和在内的代码
b:我不想使用优秀的{fmt}库,因为我正试图做我自己的事情。
我将在格式化对象的输入中使用一个字符串,以及任意数量的附加参数,比如:
// 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 !
这是我必须解决的第一个问题。我认为这个过程被称为reflection
(如果是这样的话,请告诉我(。
接下来,我需要处理数量可变的参数;第一个参数是唯一的位置性和强制性参数(我仍在试图找到一种在parameter pack
上迭代的方法(,但它是另一个问题的主题。
函数不知道传递给它的参数的名称。参数甚至不必有名称:
void foo(int x); // name of the argument is x
foo(42); // 42 has no name
正如注释中所建议的,如果您希望在字符串(要替换的值(和字符串(它们的名称(之间进行一些映射,则可以使用映射。为了避免调用方拼写出这个映射,您可以使用宏(通常是要避免的,但目前这是将变量名称作为字符串获取的唯一方法(:
#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)
}
);
}
我假设您可以使用std::to_string
,尽管没有std::to_string(const std::string&)
,因此我添加了一个自定义实现。