简体   繁体   中英

c++ multiple interfaces to the same functionality template

I have several methods that work over utf8 encoded strings that I usually keep in std::string.

In same cases though I just have const char* to the data, or the data is part of a bigger string I do not want to create a substring.

All the functionality boils down to one generic method say:

void foo(int a, int b, const char* beginStr, const char* endStr);

Now if I would like to avoid some ugliness I will create

void foo(int a, int b, const char* beginStr, const char* endStr);
void foo(int a, int b, const char* str);
void foo(int a, int b, const std::string% str);

and in some cases even:

void foo(int a, int b, const std::string::const_iterator& beginStr
                       const std::string::const_iterator& endStr);

This seems Ok, but as I mentioned I have several methods and it gets really annoying maintaining all these flavors.

What I am looking is some magic that could eliminate the need of multiplying every interface. Can some of the c++11 features help with solving this without performance impact - making it less chaty?

As mentioned in comment a wrapper as a basic_string_view may solve a part.
Variadic template may solve the other part (don't use explicitly basic_string_view ):

void foo_impl(int a, int b, const basic_string_view& str); // the real implementation

template <typename ... Ts>
void foo(int a, int b, Ts&&... args) {
    foo_impl(a, b, basic_string_view{std::forward(args...)});
}

(Deleted my prior 2 answers, hopefully third time is the charm.)

This is just Jarod42's solution, but without the dependence on basic_string_view .

struct dispatcher {
  dispatcher(const char* begin, const char* end) : begin(begin), end(end) {}
  dispatcher(const char* str) : begin(str), end(str+strlen(str)) {}
  dispatcher(const std::string& str) : begin(&*(str.begin())), end(&*(str.end())) {}
  const char* begin;
  const char* end;
};

struct main_class {
  void foo(int a, int b, const char* begin, const char* end) {
    // implementation here
  }

  template<typename... Ts>
    void foo(int a, int b, Ts&&... args) {
      dispatcher d(std::forward<Ts>(args)...);
      foo(a, b, d.begin, d.end);
    }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM