我有几种方法可以解决我通常保存在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功能可以帮助解决这个问题,而不会影响性能 - 让它变得不那么容易吗?
答案 0 :(得分:0)
如评论中所述,作为basic_string_view
的包装可以解决部分问题
Variadic模板可以解决其他部分(不要明确使用 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...)});
}
答案 1 :(得分:0)
(删除了我之前的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);
}
};