#c
#c
Вопрос:
Я хочу использовать функцию шаблона для сброса данных в файл, вот мой код:
template<typename T> // T can be `std::unordered_map<int, std::vector<double> >` or `std::unordered_map<int, std::vector<int> >`
void write_down(const std::string amp; file_path, const T amp; week) {
std::fstream f;
f.open(file_path.c_str(), std::ios::out);
if (!f) {
printf("openfile %s failedn", file_path.c_str());
return;
}
for (auto w : week) {
int date = w.first;
auto v = w.second;
char buffer[65536];
snprintf(buffer, sizeof(buffer), "%dt[", date);
std::string b = buffer;
for (auto i: v) {
char buffer[65536];
snprintf(buffer, sizeof(buffer), "%.2f", i); // here is the problem, how can i identify i is int or double!!!!!!!!!!!!!!
b = buffer;
b = ",";
}
b = "]n";
f << b;
}
f.close();
}
У меня есть два возможных типа входных параметров:
std::unordered_map<int, std::vector<double> >
и std::unordered_map<int, std::vector<int> >
единственное отличие заключается в последнем элементе, один из которых двойной, а другой — int .
но мне нужно сбросить их в файл, что означает, что snprintf должен знать тип этой переменной.
как я могу определить тип переменной в этой функции шаблона?
Комментарии:
1. Decltype может быть вашим другом. en.cppreference.com/w/cpp/language/decltype
2. Если вы используете C iostreams вместо
snprintf()
, вам не нужно беспокоиться о знании типа.snprintf()
необходимо указать, какой тип он выводит. С помощью C iostreams компилятор вычислит тип и вызовет соответствующую перегрузкуstd::ostream::operator<<()
. Одним из типов iostream являетсяstd::ostrstream
, который выводит в поток строк.
Ответ №1:
Вы используете комбинацию filestream, конкатенации строк и snprintf
. Вы могли бы удалить последние два и записать непосредственно в filestream:
for (auto w : week) {
int date = w.first;
auto v = w.second;
// buffer and snprintf replaced, no need for intermediate string b:
f << date << "t[";
for (auto i : v) {
// buffer, snprintf and string concatatenation collapsed to one line:
f << std::setprecision(2) << std::fixed << i << ',';
}
f << "]n";
}
Здесь комбинация std::setprecision(2)
и std::fixed
является эквивалентом спецификатора формата %.2f
, она не будет иметь никакого эффекта, если i
является целым числом.
Ответ №2:
Если вы настаиваете snprintf
, что-то вроде этого должно работать:
snprintf(buffer, sizeof(buffer),
std::is_same_v<decltype(i), int> ? "%d" : "%.2f", i);