这是我的自定义字符串类(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。
如何使用getline
从cin
输入我的自定义字符串类?
(我在Kubuntu 11.10上使用g ++。给模板混合不匹配提出了数十行抱怨......)
非常感谢!
答案 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);