CString a = "Hello" + "World!"; Является ли это возможным? - PullRequest
2 голосов
/ 16 мая 2010

Я делаю свою собственную строку class, и я хотел бы убедиться, что CString a = "Hello " + "World!"; работает (т.е. не выдает ошибку компилятора, такую ​​как: cannot add 2 pointers).

Моя строка class автоматически преобразуется в char* при необходимости, и, таким образом, запись printf(a) не нарушит код.

Есть ли способ заменить поведение компилятора вокруг символов ? (то есть между кавычками "abc"). Или, альтернативно, изменить поведение оператора + для обработки строк ?

Ответы [ 2 ]

9 голосов
/ 16 мая 2010

Вы не можете сделать точно , потому что вы можете перегружать операторы только для типов классов, а строковый литерал не имеет типа класса.

Вы можете воспользоваться объединением строковых литералов, которое происходит во время предварительной обработки:

CString a = "Hello " "World!";

или вы можете создать CString временный файл и добавить к нему:

CString a = CString("Hello ") + "World!";

или у вас может быть CString конструктор, который принимает более одного аргумента:

CString a("Hello ", "World!");
6 голосов
/ 16 мая 2010

Правильный ответ

Нет. Вы не можете перегружать операторы для встроенных модулей, таких как указатели.

Джеймс МакНеллис уже ответил на вопрос, поэтому я не буду уточнять.

Возможная альтернатива ...

(я использую std :: string, потому что у меня нет информации о вашей внутренней строке)

Использование typedef добавит немного сахара в ваш синтаксис:

typedef std::string S_ ;

int main(int argc, char* argv[])
{
   std::string s = S_("Hello") + S_(" World") ;

   std::cout << "s : " << s << std::endl ;

   return 0 ;
}

Но тогда я бы не стал загрязнять глобальное пространство имен двухсимвольным символом только для небольшого количества сахара ... И, насколько я знаю, код неэффективен (созданы два строковых объекта плюс один временный, без гарантировать, что компилятор все это оптимизирует ...)

Ради любопытства ...

Любопытно, что, обернув строку в тонкий класс, вы можете «добавить» эти два указателя.

Сначала давайте создадим оболочку:

class StringThinWrapper
{
   public :

      StringThinWrapper(const char * p) : m_p(p) {}
      operator const char * () const { return m_p ; }

   private :
      const char * const m_p ;
} ;

Как видите, он одновременно встроенный и ничего не будет делать ... Тем не менее, он может привести себя к константному символу * указателю (этот вид взлома опасен, поэтому убедитесь, что это именно то, что вы хотите сделать) .

Тогда для этой обёртки давайте перегрузим оператор сложения:

inline std::string operator + (const StringThinWrapper & lhs, const StringThinWrapper & rhs)
{
   std::string s(lhs) ;
   s += rhs ;
   return s ;
}

А теперь давайте напишем функцию main, используя оболочку, typedefed для простоты использования:

typedef StringThinWrapper S_ ;

int main(int argc, char* argv[])
{
   std::string s = S_("Hello") + S_(" World") ;

   std::cout << "s : " << s << std::endl ;

   return 0 ;
}

, который компилирует и дает следующий результат:

s: Hello World

Отказ от ответственности: я просто хотел поиграть с идеей, которую дал мне ваш вопрос, и поделиться ею с вами. Не применяйте такой код только потому, что можете. Действительно, этот код должен быть доработан, чтобы эффективно охватить все случаи, прежде чем даже использоваться, и даже тогда простой typedef std::string S_ ; будет лучше, ИМХО.

AFAIK, я бы не стал его использовать, потому что я доволен текущим API STL.

А как насчет C ++ 0x?

В C ++ 0x вы сможете создавать свои собственные литералы. Код будет выглядеть примерно так:

std::string operator "str"(const char * p)
{ 
    return std::string(p); 
}

И вы будете использовать его так:

int main(int argc, char * argv[])
{
   std::string s = "Hello"str + " World"str ;

   std::cout << "s : " << s << std::endl ;

   return 0 ;
}

Для получения дополнительной информации см. Следующий вопрос SO: Какие новые возможности пользовательские литералы добавляют в C ++? .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...