2012-03-05 2 views
0

Это мой пользовательский класс строка (xstring.hpp):std :: getline (std :: cin, custom_class); несоответствие типов

#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. Дает десятки линий жалуются на несовпадений шаблон смеси ...)

Спасибо так много!

+0

Я честно не понимаю, зачем вы хотите это сделать. Зачем делать еще одну строку? –

+0

Поскольку мне нужны некоторые пользовательские функции, такие как токенизация, некоторые пользовательские виды преобразований и манипуляций, ... а также мне нужно, чтобы она работала на всех языках, поэтому я использовал шаблон. :-) – Haix64

+2

@BillyIneal: Это не другая строка, похожая на внешний вид; это оболочка для добавления функций в существующий класс строк. Хотя я не могу сказать, зачем вам нужны такие функции, а не функции, отличные от членов. –

ответ

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), никакого вычитания типа не требуется, поэтому оператор преобразования будет рассмотрен.

+0

Это * делает * принимать во внимание неявные преобразования, а не только определенные пользователем преобразования. – Xeo

+0

@Xeo: Не уверен, что вы имеете в виду. –

+0

'template struct X {}; шаблон f (X const volatile *); X x; f (&x); 'имеет встроенное неявное преобразование из' X * 'в' Xconst volatile * '. –

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); 
+0

Я очень ценю это, спасибо! Однако я все равно буду искать ответ на решение функций MEMBER. Но спасибо в любом случае ;-) – Haix64

+0

И большое спасибо Майку. Это то, чем я был. Спасибо. :-) – Haix64

Смежные вопросы