2

So I have come across a problem where I have a function with multiple parameters. Out of usability I started overloading it so that for instace I can pass a std::string instead of a std::fstream instance. In this overload a new std::fsteam will be constructed from that string and then the other function will be called. Like this:

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

  func(file)
}

void func(std::fstream & file) {
  // ...
}

This all works fine. But when you start doing this for more than one parameter or more than 2 possible types everything starts becoming a mess and you might have to write lots of overloads with duplicate code etc.
So I was wondering if there was a more elegant solution to this problem for as many parameters as you need.

I know this problem is not specific to C++ but I'm interested in solutions for the problem in C++.

7
  • 3
    Have you heard of templates? Commented Nov 7, 2016 at 13:05
  • Yes. However I'm not sure how I could use them in this specific case. Commented Nov 7, 2016 at 13:06
  • 3
    You could specialize templates and you could also specify conditions for certain types with type traits. Commented Nov 7, 2016 at 13:07
  • Make the parameter a template, (try to) construct an fstream from that, pass it on. Why does that not work for you? Commented Nov 7, 2016 at 13:08
  • 3
    Related, but it mostly says "Don't worry about it". The problems caused by passing the wrong types are a compilation error, which is pretty much the best thing that can happen when you do something wrong in C++. Commented Nov 7, 2016 at 13:17

2 Answers 2

2

One possible solution is to use helper classes:

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

A helper class for each parameter contains overloaded constructors for each possible type that can be passed in. You end up with a single func() to implement.

Within each helper class you'll need to figure out how to correctly store each parameter, which is going to be a different question.

With C++14 you could also make use of std::variant here, as well.

Sign up to request clarification or add additional context in comments.

3 Comments

Using helper classes seems a little excessive.
Not when you have four or five parameters, and every parameter can be any available alternative. The choices are, either: dozens, if not hundreds, of overloaded functions; template-generated code bloat; or this. Choose one.
In the latter case I agree. It's really a matter of preference and circumstance I'd say.
1

So I found a pretty decent and expandable solution:

Let's assume we have a function that accepts 3 paramters of the type type_right1, type_right2 and type_right3 but we also want to provide it with the additional overloads for the respective types type_right1, type_wrong2 and type_wrong3. We also asume to get from type_wrongX to type_rightX we just call the constructor of the latter and pass the former. The code looks like this:

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
}

This solution can be easily expanded with both more parameters and more than two types per parameter and requires a lot less writing and also just generates the functions you actually need!
Thank you for your help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.