具有通用输入参数的函数
Function with generic input parameters
我对 C++ 比较陌生。我写了函数WriteToFile
,它写在文本文件(路径由字符串a
指定)二维数组(存储在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);
}
现在我希望这个函数也能处理 int
和 double
数组。对于 int
它只会按原样打印数字,对于双精度 %5.10lf
必须在 fprintf
中使用。我知道,这是绝对可能的。我发现了一些类似的东西,但不知道如何处理输入参数。当然,我可以编写 3 个不同的函数,但我想学习如何编写泛型函数。
谢谢
一个想法是
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 }
如果需要为每种类型使用不同的格式字符串,可以使用模板函数并将格式字符串作为参数传入:
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]);
...
}
"Now I want this function to deal also with int
and double
arrays. "
您可以使用模板函数来处理不同类型的数组,并使用 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();
}
您可以考虑针对不同的格式化需求进行专门的实施。
您可以使用函数模板和一些辅助函数来获取格式字符串。
这是一个工作程序。
#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);
}
您有重载和模板函数等选项。我只想介绍一个C++11自带的能力。使用 std::is_same
.
它有利也有弊。例如,假设输入类型限于 int
和 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]);
...
}
请注意,这种方法不利于泛化,您的代码并不是尽可能通用。
我对 C++ 比较陌生。我写了函数WriteToFile
,它写在文本文件(路径由字符串a
指定)二维数组(存储在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);
}
现在我希望这个函数也能处理 int
和 double
数组。对于 int
它只会按原样打印数字,对于双精度 %5.10lf
必须在 fprintf
中使用。我知道,这是绝对可能的。我发现了一些类似的东西,但不知道如何处理输入参数。当然,我可以编写 3 个不同的函数,但我想学习如何编写泛型函数。
谢谢
一个想法是
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 }
如果需要为每种类型使用不同的格式字符串,可以使用模板函数并将格式字符串作为参数传入:
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]);
...
}
"Now I want this function to deal also with
int
anddouble
arrays. "
您可以使用模板函数来处理不同类型的数组,并使用 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();
}
您可以考虑针对不同的格式化需求进行专门的实施。
您可以使用函数模板和一些辅助函数来获取格式字符串。
这是一个工作程序。
#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);
}
您有重载和模板函数等选项。我只想介绍一个C++11自带的能力。使用 std::is_same
.
它有利也有弊。例如,假设输入类型限于 int
和 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]);
...
}
请注意,这种方法不利于泛化,您的代码并不是尽可能通用。