同一参数具有多个类型的函数

Function with multiple types for same parameter

本文关键字:类型 函数 参数      更新时间:2023-10-16

所以我遇到了一个问题,我有一个函数有多个参数。出于可用性,我开始重载它,以便例如我可以传递std::string而不是std::fstream实例。在这个重载中,将从该字符串构造一个新的std::fsteam,然后调用另一个函数。这样的:

void func(const std::string & filename) {
  std::fstream file(filename);
  func(file)
}
void func(std::fstream & file) {
  // ...
}

这一切都很好。但是当你开始为多个参数或超过2个可能的类型这样做时,一切都开始变得一团糟,你可能不得不写很多重复代码的重载等等。
所以我想知道是否有一个更优雅的解决方案来解决这个问题,因为你需要尽可能多的参数。

我知道这个问题不是c++特有的,但是我对c++中解决这个问题的方法很感兴趣。

一个可能的解决方案是使用辅助类:

class param1 {
public:
    param1(const std::string & filename)
          : filename(filename), file(nullptr)
    {
    }
    param1(std::fstream &file) : file(&file)
    {
    }
    std::string filename;
    std::fstream *file;
};
class param2 {
public:
    param2(int flag);
    param2(some_particular_class &classptr);
    // etc...
};
void func(const param1 &p1, const param2 &p2);

每个形参的辅助类包含可传入的每种可能类型的重载构造函数。您最终只需要实现一个func()

在每个helper类中,您需要弄清楚如何正确存储每个参数,这将是一个不同的问题。

在c++ 14中,您也可以在这里使用std::variant

所以我找到了一个相当体面和可扩展的解决方案:

让我们假设我们有一个函数,它接受type_right1, type_right2type_right3类型的3个参数,但我们还希望为type_right1, type_wrong2type_wrong3类型提供额外的重载。我们还假设要从type_wrongX得到type_rightX,只需调用后者的构造函数并传递前者。代码看起来像这样:

template<class T1, class T2>
void func(type_wrong1 arg1, T1 arg2, T2 arg3) {
  func(type_right1(arg1), arg2, arg3);
}
template<class T1>
void func(type_right1 arg1, type_wrong2 arg2, T1 arg3) {
  func(arg1, type_right2(arg2), arg3);
}
void func(type_right1 arg1, type_right2 arg2, type_wrong3 arg3) {
  func(arg1, arg2, type_right2(arg3));
}
void func(type_right1 arg1, type_right2 arg2, type_right3 arg3) {
  // actual function
}

这个解决方案可以很容易地扩展为更多的参数和每个参数超过两个类型,需要更少的编写,也只是生成你真正需要的函数!
谢谢你的帮助。