std :: getline(std :: cin,custom_class);类型不匹配

时间:2012-03-05 17:26:40

标签: c++ oop templates cin

这是我的自定义字符串类(xstring.hpp):

#include <vector>
#include <sstream>

namespace
{
    using std::vector;
    using std::istringstream;

    template <class strT>
    class xstring_base
    {
        private:
            strT str;

        public:
            operator strT&() {return str;}
            vector<strT>* tokenize();

            // constructors
            xstring_base<strT>(strT);
    };
}
#include "xstring.cpp"

#include <string>
typedef xstring_base<std::string> xstring;

我已经让operator strT&()模仿标准库的字符串行为,无论何时需要,当我用C风格的字符串初始化它时,这个类工作得很好,甚至包含非ASCII代码,例如阿拉伯语,但是std::getline抱怨不支持xstring。

如何使用getlinecin输入我的自定义字符串类?

(我在Kubuntu 11.10上使用g ++。给模板混合不匹配提出了数十行抱怨......)

非常感谢!

2 个答案:

答案 0 :(得分:2)

std::getline是一个功能模板,如下所示:

template< class CharT, class Traits, class Allocator >
std::basic_istream<CharT,Traits>& getline( std::basic_istream<CharT,Traits>& input,
                                           std::basic_string<CharT,Traits,Allocator>& str );

当您致电std::getline(std::cin, x)时,您不提供模板参数。这意味着必须从参数中推断出类型。

但是,类型推导算法不会考虑用户定义的转换。因此,不使用转换运算符。如果您编写std::getline<char, std::char_traits<char>, std::allocator<char>>(std::cin, x),则不需要进行类型推导,因此将考虑转换运算符。

答案 1 :(得分:1)

这种失败的原因相当晦涩 - 基本上,std::getline是一个模板,只有当参数是std::basic_string的特化时才能推导出模板参数(例如std::string }) - 在这种情况下不考虑类型转换。

最好的解决方案不是尝试包装现有的字符串类型,而是编写非成员函数来添加所需的功能:

template <typename String>
std::vector<String> tokenise(String const &);

如果由于某种原因确实需要包装器类型,则必须显式转换为字符串类型,或者提供模板参数:

std::getline(std::cin, static_cast<std::string&>(xs));
std::getline<char, std::char_traits<char>, std::allocator<char> >(std::cin, xs);