Mikhail Genkin
Mikhail Genkin

Reputation: 3460

Function with generic input parameters

I am relatively new to c++. I wrote function WriteToFile, which writes in text file (path is specified by string a) 2D array (stored in 0-row major order, x rows, y columns):

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

Now I want this function to deal also with int and double arrays. For int it will just print numbers as it is, and for double %5.10lf must be used in fprintf. I know, that it is absolutely possible. I found couple similar things, but didn't get how do deal with input arguments. Of course, I can write 3 different functions, but I want to learn how can I write generic function.

Thanks

Upvotes: 4

Views: 2283

Answers (5)

masoud
masoud

Reputation: 56479

You have options such as overloading and template functions. I just want to introduce an ability which comes with C++11. Using std::is_same.

It has its pros and cons. For example, assume the input type is limited to int and float:

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

   ...
}

Note that, this approach is against generalization and your code is not as generic as possible.

Upvotes: 1

R Sahu
R Sahu

Reputation: 206577

You can use a function template and some helper functions to get the format string.

Here's a working program.

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

Upvotes: 3

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

"Now I want this function to deal also with int and double arrays. "

You can use a templated function to handle different types of arrays, and use the c++ standard I/O library

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();
}

You may consider to have specialized implementations for different formatting needs.

Upvotes: 3

John Stevens
John Stevens

Reputation: 216

If you need to use a different format string for each type, you can use a templated function and pass in the format string as a parameter:

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]); 
...
}

Upvotes: 0

Tasos Vogiatzoglou
Tasos Vogiatzoglou

Reputation: 2453

An idea would be

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

and then a

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

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

Upvotes: -2

Related Questions