0

我使用这种方法为字符串创建了一个不区分大小写的 typedef。现在,我正在尝试将 a 转换std::stringci_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_castdynamic_cast没有成功。我怎样才能做到这一点?

4

2 回答 2

1

您的两种类型不同,因此您不能将构造函数与常规std::string. 但是您的字符串仍然能够复制 C 字符串,所以这应该可以工作:

std::string s{"a"};
ci_string cis{ s.data() }; // or s.c_str(), they are the same
于 2015-11-15T18:46:46.050 回答
1

std::string并且ci_string不相关的类型。为什么会static_castdynamic_cast能够转换它们?请记住:同一模板的两个不同实例是不相关的类型,并且可能完全不兼容。

放弃重载的想法operator=或自动执行转换的一些魔法。您有两种不相关的类型。但是它们都提供了成员函数,您可以成功地使用这些函数将char元素从一个复制到另一个。

只需编写一个简单的转换函数,利用两者std::stringci_string将它们value_type定义为的事实char,并适当地使用std::basic_string的构造函数之一,一个接受指向原始数据的指针,或者一个接受两个构成范围的迭代器。

这是一个完整的例子:

#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";
}
于 2015-11-15T20:16:22.163 回答