как получить тип переменной в шаблоне?

#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);