【问题标题】:c++ multiple interfaces to the same functionality templatec++ 多个接口到同一个功能模板
【发布时间】:2015-12-31 23:59:30
【问题描述】:

我有几种方法可以处理我通常保存在 std::string 中的 utf8 编码字符串。

在同样的情况下,虽然我只有 const char* 到数据,或者数据是更大字符串的一部分,但我不想创建子字符串。

所有功能都归结为一种通用方法:

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

现在,如果我想避免一些丑陋,我会创造

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

在某些情况下甚至:

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

这看起来不错,但正如我提到的,我有几种方法,维护所有这些风格真的很烦人。

我正在寻找一些可以消除增加每个接口的需要的魔法。某些 c++11 功能能否在不影响性能的情况下帮助解决这个问题 - 让它不那么啰嗦?

【问题讨论】:

  • 为什么有些方法有两个 const char* 而另一些有一个?
  • 当你传递一个范围时有两个句柄,一个是当你只知道开始并且它是零终止时。
  • @Amit 我可能更喜欢手动维护它们而不是宏,但是现在当你提到它时,即使使用宏似乎也不是那么容易。
  • 不在 C++11 中,但 en.cppreference.com/w/cpp/experimental/basic_string_view 在推出时会很好。或者您可以只使用实验性实现。
  • 一个经验法则是,大多数你重复做的事情有小的变化(例如函数名),你应该可以用宏来做。但这并不是说一切都可以而且应该这样做。

标签: c++ c++11 overloading


【解决方案1】:

正如评论中提到的,basic_string_view 的包装器可以解决一部分问题。
可变参数模板可以解决其他部分(不要显式使用 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...)});
}

【讨论】:

    【解决方案2】:

    (删除了我之前的2个答案,希望第三次是魅力。)

    这只是 Jarod42 的解决方案,但不依赖于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);
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-22
      • 1970-01-01
      相关资源
      最近更新 更多