具有通用输入参数的函数

时间:2015-02-10 17:45:53

标签: c++ generics

我对c ++比较陌生。我写了函数WriteToFile,它写入文本文件(路径由字符串a指定)2D数组(存储在0行主要顺序,x行,y列):

void WriteToFile(std::string a, const float *img, const int x, const int y) {
    FILE *pFile;
    const char * c = a.c_str();
    pFile = fopen(c, "w");
    for (int i = 0; i < x; i++){
        for (int j = 0; j < y; j++)
            fprintf(pFile, "%5.5f\t", img[i*y + j]);
        fprintf(pFile, "\n");
    }
    fclose(pFile);
}

现在我希望此函数同时处理intdouble数组。对于int,它只会按原样打印数字,并且必须在%5.10lf中使用双fprintf。我知道,这绝对是可能的。我发现了几个类似的东西,但没有得到如何处理输入参数。当然,我可以编写3个不同的函数,但我想学习如何编写泛型函数。

由于

5 个答案:

答案 0 :(得分:3)

  

&#34;现在我希望此功能同时处理intdouble数组。 &#34;

您可以使用模板化函数来处理不同类型的数组,并使用c ++标准I / O库

template <typename T>
void WriteToFile(std::string a, const T *img, const int x, const int y) {
    std::ofstream file(a);

    for (int i = 0; i < x; i++){
        for (int j = 0; j < y; j++)
            file << std::fixed << std::setw(5) << std::setprecision(5) 
                 << img[i*y + j] << "\t" << std::endl;
    }
    file.close();
}

您可能会考虑针对不同的格式需求进行专门的实施。

答案 1 :(得分:3)

您可以使用函数模板和一些辅助函数来获取格式字符串。

这是一个工作计划。

#include <cstdio>
#include <string>

template <typename T> char const* getFormatString();

template <> char const* getFormatString<int>()
{
   return "%d\t";
}

template <> char const* getFormatString<float>()
{
   return "%5.5f\t";
}

template <> char const* getFormatString<double>()
{
   return "%15.10lf\t";
}

template <typename T>
void WriteToFile(std::string a, const T *img, const int x, const int y) {
    FILE *pFile;
    const char * c = a.c_str();
    pFile = fopen(c, "w");
    for (int i = 0; i < x; i++){
        for (int j = 0; j < y; j++)
            fprintf(pFile, getFormatString<T>(), img[i*y + j]);
        fprintf(pFile, "\n");
    }
    fclose(pFile);
}

int main()
{
   int img1[] = {1, 1, 1, 1};
   float img2[] = {1, 1, 1, 1};
   double img3[] = {1, 1, 1, 1};
   WriteToFile("int.img", img1, 2, 2);
   WriteToFile("float.img", img2, 2, 2);
   WriteToFile("double.img", img3, 2, 2);
}

答案 2 :(得分:0)

如果需要为每种类型使用不同的格式字符串,可以使用模板化函数并将格式字符串作为参数传递:

template<typename T> void WriteToFile(std::string a, const T *img, 
                      const int x, const int y, std::string formatStr) {
...
       fprintf(pFile, formatStr.c_str(), img[i*y + j]); 
...
}

答案 3 :(得分:0)

您可以选择重载和模板功能。我只是想介绍一下C ++ 11附带的功能。使用std::is_same

它有其优点和缺点。例如,假设输入类型仅限于intfloat

#include <type_traits>

template <typename T>
void WriteToFile(std::string a, const T *img, const int x, const int y)
{
   const char *format = std::is_same<T, int>::value? "%i\t" : "%5.5f\t";

   ...

      fprintf(pFile, format, img[i*y + j]);

   ...
}

请注意,这种方法不会泛化,您的代码也不尽如人意。

答案 4 :(得分:-2)

一个想法是

template <typename T>
void WriteToFile(std::string a, const T *img, const int x, const int y) {
}

然后是

inline
void write(FILE *file, double) { //write double }

inline
void write(FILE *file, int) { // write }