Предположим следующий код, который является крошечной заменой sprintf. (_Itoa и подобные ему просто использовались для краткости кода.)
#include <cstdlib>
#include <string>
class Arg {
public:
Arg(const std::string& s) :m_str(s) {}
Arg(const char* s) : m_str(s) {}
Arg(int digi, double number) {char buf[128]; m_str = _gcvt(number, digi, buf);}
operator const std::string& ()const { return m_str; }
private:
std::string m_str;
};
class Format {
public:
Format(/*const char* format, */std::initializer_list<Arg> args); // see below
const std::string& str()const { return m_str; }
private:
std::string m_str;
};
Format::Format(/*const char* format, */std::initializer_list<Arg> args) {
auto arg = args.begin();
auto format = std::string(*arg++);
for(const char* c = format.c_str(); *c!='\0'; ++c) {
if(*c=='%') { m_str+=*arg++; }
else { m_str+=*c; }
}
}
int main() {
std::string test1 = Format{"test Double:% String:%", {5, 456.78}, "foo"}.str();
// I want to make this work. See the braces.
std::string test2 = Format("test Double:% String:%", {5, 456.78}, "foo").str();
return 0;
}
Видите ли, я хочу передать аргументы, ограниченные типом "Arg", но используйте конструктор, который использует, например, varadi c шаблонов вместо initializer_list <> для лучшей читабельности.
Я пытался:
template<typename... T>
Format(T&& ... args) : Format(std::forward<Args>(args)...) {}
Но я получаю:
error C2440: '<function-style-cast>': cannot convert from 'initializer list' to 'Format'
note: No constructor could take the source type, or constructor overload resolution was ambiguous