将 std::string 转换为 ci_string
Convert std::string to ci_string
我使用 this approach 为字符串创建了一个不区分大小写的 typedef。现在,我正在尝试将 std::string
转换为 ci_string
。以下所有抛出编译器错误:
std::string s {"a"};
ci_string cis {s};
ci_string cis (s);
ci_string cis {(ci_string)s};
ci_string cis ((ci_string)s);
ci_string cis = s;
我花了一些时间试图找出如何重载 =
运算符,并且我尝试使用 static_cast
和 dynamic_cast
但没有成功。我该怎么做?
你的两个类型不同,所以你不能使用正则的构造函数std::string
。但是你的字符串仍然能够复制 C 字符串,所以这应该有效:
std::string s{"a"};
ci_string cis{ s.data() }; // or s.c_str(), they are the same
std::string
和 ci_string
是 不相关的类型 。为什么 static_cast
或 dynamic_cast
能够转换它们?请记住:同一模板的两个不同实例是不相关的类型,可能完全不兼容。
放弃重载的想法 operator=
或一些自动执行转换的魔法。你有两个不相关的类型。但是它们都提供了成员函数,您可以成功地使用这些成员函数将 char
元素从一个元素复制到另一个元素。
只需编写一个简单的转换函数,利用 std::string
和 ci_string
都将其 value_type
定义为 char
的事实,并适当地使用其中之一std::basic_string
's constructors,要么采用指向原始数据的指针,要么采用两个形成范围的迭代器。
这是一个完整的例子:
#include <string>
#include <iostream>
struct ci_char_traits : public std::char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); }
static int compare(const char* s1, const char* s2, size_t n) {
while( n-- != 0 ) {
if( toupper(*s1) < toupper(*s2) ) return -1;
if( toupper(*s1) > toupper(*s2) ) return 1;
++s1; ++s2;
}
return 0;
}
static const char* find(const char* s, int n, char a) {
while( n-- > 0 && toupper(*s) != toupper(a) ) {
++s;
}
return s;
}
};
typedef std::basic_string<char, ci_char_traits> ci_string;
ci_string to_ci_string(std::string const& src)
{
return ci_string(src.begin(), src.end());
// or:
// return ci_string(src.c_str());
}
int main()
{
std::string s {"a"};
auto cis = to_ci_string(s);
std::cout << cis.c_str() << "\n";
}
我使用 this approach 为字符串创建了一个不区分大小写的 typedef。现在,我正在尝试将 std::string
转换为 ci_string
。以下所有抛出编译器错误:
std::string s {"a"};
ci_string cis {s};
ci_string cis (s);
ci_string cis {(ci_string)s};
ci_string cis ((ci_string)s);
ci_string cis = s;
我花了一些时间试图找出如何重载 =
运算符,并且我尝试使用 static_cast
和 dynamic_cast
但没有成功。我该怎么做?
你的两个类型不同,所以你不能使用正则的构造函数std::string
。但是你的字符串仍然能够复制 C 字符串,所以这应该有效:
std::string s{"a"};
ci_string cis{ s.data() }; // or s.c_str(), they are the same
std::string
和 ci_string
是 不相关的类型 。为什么 static_cast
或 dynamic_cast
能够转换它们?请记住:同一模板的两个不同实例是不相关的类型,可能完全不兼容。
放弃重载的想法 operator=
或一些自动执行转换的魔法。你有两个不相关的类型。但是它们都提供了成员函数,您可以成功地使用这些成员函数将 char
元素从一个元素复制到另一个元素。
只需编写一个简单的转换函数,利用 std::string
和 ci_string
都将其 value_type
定义为 char
的事实,并适当地使用其中之一std::basic_string
's constructors,要么采用指向原始数据的指针,要么采用两个形成范围的迭代器。
这是一个完整的例子:
#include <string>
#include <iostream>
struct ci_char_traits : public std::char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); }
static int compare(const char* s1, const char* s2, size_t n) {
while( n-- != 0 ) {
if( toupper(*s1) < toupper(*s2) ) return -1;
if( toupper(*s1) > toupper(*s2) ) return 1;
++s1; ++s2;
}
return 0;
}
static const char* find(const char* s, int n, char a) {
while( n-- > 0 && toupper(*s) != toupper(a) ) {
++s;
}
return s;
}
};
typedef std::basic_string<char, ci_char_traits> ci_string;
ci_string to_ci_string(std::string const& src)
{
return ci_string(src.begin(), src.end());
// or:
// return ci_string(src.c_str());
}
int main()
{
std::string s {"a"};
auto cis = to_ci_string(s);
std::cout << cis.c_str() << "\n";
}