5

I'm creating an API, and I want to overload a function for strip:

QString MyClass::strip();
QString MyClass::strip(QRegularExpression open);
QString MyClass::strip(QRegularExpression close);
QString MyClass::strip(QRegularExpression open, QRegularExpression close);

Obviously the second and third conflict.

What is the recommended style for C++ and Qt programmers to restructure this?

Anon
  • 3,565
  • 3
  • 27
  • 45
  • 1
    [Default arguments?](http://en.cppreference.com/w/cpp/language/default_arguments) – Dawnkeeper Jan 13 '16 at 13:01
  • 1
    @Dawnkeeper Does that solution work, when both parameters are not necessarily used? Think of it as "Dinner" and "Desert" ; Maybe I only want dinner, but not desert, or maybe I want desert, but not dinner. Maybe I want both! Maybe I want neither! – Anon Jan 13 '16 at 13:11
  • 7
    You should give your functions different names, like `stripOpen` and `stripClose`. – gardenhead Jan 14 '16 at 02:15
  • 1
    Just keep #4 and handle the case where open or close are null. – Florian F Jan 15 '16 at 18:05
  • What gardenhead says. Don't be too smart about this. You may come up with a technical solution that works and feel good about it but you should first consider what it looks like at the client's end. Does it still read well? Is it obvious what your methods do when the user hits the dot and gets presented a list of methods? – Martin Maat Jan 25 '21 at 18:06

3 Answers3

8

What about creating a class to hold your arguments? This class would contain both open and close parameters and either of them could be NULL. Then, there will be only one strip method with above class as argument and method will decide if it wants to use open/close if they are set.

Euphoric
  • 36,735
  • 6
  • 78
  • 110
  • Very interesting suggestion; I have never used this method. Can you give me an idea of what it would look like? Why a class, and not a struct? – Anon Jan 13 '16 at 13:33
  • 3
    @Akiva Well, I don't think it matters if struct or class in this case. – Euphoric Jan 13 '16 at 13:34
  • @Akiva C++ has *class types* defined with both `struct` and `class` keywords – Caleth Jan 25 '21 at 17:31
5

There are many options, it's your tradeoff which to take:

Decision at runtime:

  1. Add a defaulted bool argument:

     QString MyClass::strip(QRegularExpression regex, bool close=false);
     // Mimic the two-regex-variants interface as good as possible
    
  2. Use scoped enum's and no default as a variant on 1 which is more descriptive:

     enum class option { open, close };
     QString MyClass::strip(QRegularExpression regex, option open_close);
    
  3. Use std::experimental::optional or something like that, maybe from boost.

  4. Find out that a specific regex does nothing, and document that as the no-op default.

Decision at compiletime:

  1. Use overloads replacing one argument with std::nullptr_t:

     QString MyClass::strip(std::nullptr_t open, QRegularExpression close);
     QString MyClass::strip(QRegularExpression open, std::nullptr_t close = {});
    
  2. Use tags to avoid any overhead:

     constexpr struct open_t {} open;
     constexpr struct close_t {} close;
     QString MyClass::strip(open_t, QRegularExpression regex);
     QString MyClass::strip(close_t, QRegularExpression regex);
    
     // Call it like this:
     object.strip(object.open, regex);
    
  3. Bite the bullet and name those functions differently:

     QString MyClass::strip_open(QRegularExpression regex);
     QString MyClass::strip_close(QRegularExpression regex);
    
  4. Consider whether making the open-regex and the close-regex different types makes sense. To be truthful, I doubt it here, but where appropriate that's the best option.

Deduplicator
  • 8,591
  • 5
  • 31
  • 50
  • 2
    6. Don;t provide them Allow QString MyClass::strip(QRegularExpression open, QRegularExpression close); to take NULL parameters. – mattnz Jan 14 '16 at 00:15
  • @mattnz Ohhh that is an interesting solution! Question is though; is there a naming scheme for the parameters that would indicate that null values are accepted? Perhaps Defaulting them both to "NULL" values? – Anon Jan 15 '16 at 05:43
  • 1
    @Akiva: Elaborated on a way to achieve something like that. As an aside, you can combine using an optional type, replacing positional arguments with `std::nullptr_t` and using a "do nothing"-regex. – Deduplicator Jan 15 '16 at 13:31
4

I would suggest

QString MyClass::strip();
QString MyClass::strip(QRegularExpression regex, bool opening=false); 
QString MyClass::strip(QRegularExpression open, QRegularExpression close);

and perhaps

QString MyClass::strip_open(QRegularExpression regex);
QString MyClass::strip_close(QRegularExpression regex);

or replace the bool opening with e.g.

enum stripping_mode {Strip_Open, Strip_Close};;

or make even it a class enum

Basile Starynkevitch
  • 32,434
  • 6
  • 84
  • 125