std :: codecvt :: do_in方法重载与其余基本方法 [英] std::codecvt::do_in method overloading vs the rest of base methods

查看:129
本文介绍了std :: codecvt :: do_in方法重载与其余基本方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经重载了std::codecvtdo_in方法:

#include <iostream>
#include <locale>
#include <string>

class codecvt_to_upper : public std::codecvt<char, char, std::mbstate_t> {
public:

    explicit codecvt_to_upper(size_t r = 0) : std::codecvt<char, char, 
                                                          std::mbstate_t>(r) {}
protected:
    result do_in(state_type& state, const extern_type* from,
                 const extern_type* from_end, const extern_type*& from_next,
                 intern_type* to, intern_type* to_end, intern_type*& to_next)
                   const;

    result
    do_out(state_type& __state, const intern_type* __from,
            const intern_type* __from_end, const intern_type*& __from_next,
            extern_type* __to, extern_type* __to_end,
            extern_type*& __to_next) const {
        return codecvt_to_upper::ok;
    }

    result
    do_unshift(state_type& __state, extern_type* __to,
            extern_type* __to_end, extern_type*& __to_next) const {
        return codecvt_to_upper::ok;
    }

    int
    do_encoding() const throw () {
        return 1;
    }

    bool
    do_always_noconv() const throw () {
        return false;
    }

    int
    do_length(state_type&, const extern_type* __from,
            const extern_type* __end, size_t __max) const {
        return 1;
    }

    int
    do_max_length() const throw () {
        return 10;
    }
};

codecvt_to_upper::result codecvt_to_upper::do_in(state_type& state, 
                  const extern_type* from, const extern_type* from_end, const 
                  extern_type*& from_next, intern_type* to, intern_type* 
                  to_end, intern_type*& to_next) const {
    codecvt_to_upper::result res = codecvt_to_upper::error;
    const std::ctype<char>& ct = std::use_facet<std::ctype<char> >( 
                                                               std::locale());

    const extern_type* p = from;
    while( p != from_end && to != to_end) {
        *to++ = ct.toupper( *p++);
    }
    from_next = p;
    to_next = to;
    res = codecvt_to_upper::ok;
    return res;
}

并以此方式使用:

int main(int argc, char** argv) {

    std::locale ulocale( std::locale(), new codecvt_to_upper);

    std::cin.imbue( ulocale);

    char ch;
    while ( std::cin >> ch) {
        std::cout << ch;
    }
    return 0;
}

但未调用do_in重载.我是否已正确超载? 我必须更改std::codecvt<char, char, std::mbstate_t>的哪种方法(以及如何更改),以使构面调用do_in方法?

but do_in overload is not being called. Have I overloaded it correctly? Which method of std::codecvt<char, char, std::mbstate_t> (and how) do I have to change to make my facet calling do_in method?

推荐答案

我认为应该首先解决的问题是std::codecvt家族方面仅由std::basic_filebuf使用,因为仅在处理时需要代码转换外部设备.在您的代码中,您正在将语言环境放入std::cin中,该语言具有一个进行代码转换的缓冲区.

I think the first thing that should be addressed is that the std::codecvt family facets are only used by std::basic_filebuf because code conversion is only needed when dealing with an external device. In your code, you were imbuing the locale into std::cin, which has a buffer that does not do code conversion.

当然,仍然可以在程序内执行代码转换,但是,阻止您的代码正常工作的方面是它继承自不能执行转换的std::codecvt<>专业化. std::codecvt<>char => char专业化没有定义转换,因此不会调用do_in(),因为不必在两种类型之间进行转换.

Of course, it is still possible to perform code conversion within the program, but the thing about your facet that was preventing your code from working was that it inherited from a specialization of std::codecvt<> that cannot do conversions. The char => char specialization of std::codecvt<> doesn't define a conversion, therefore do_in() won't be called because it is unnecessary to convert between the two types.

我尝试运行您的代码,但将继承的构面更改为std::codecvt<wchar_t, char, std::mbstate>,并使用了宽字符文件流和

I tried running your code, but changing the inherited facet to std::codecvt<wchar_t, char, std::mbstate> and used wide-character file streams and it worked.

如果您希望它也适用于窄字符流,我建议创建一个流缓冲区,该缓冲区通过underflow()转发大写字符.

If you want this to work for narrow-character streams as well I would suggest creating a stream buffer that forwards uppercase characters through underflow().

这篇关于std :: codecvt :: do_in方法重载与其余基本方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆