Значение кавычек C ++ в g ++ против MSVC - PullRequest
0 голосов
/ 28 октября 2011

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

Итак,

В MSVC текст внутри кавычек "как этот" взят, я думаю, как std :: string или, может быть, std :: string &. В g ++ / gcc это всегда выглядит как const char *. Правда?

Я нашел фрагмент кода, с которым хотел поиграть, и он содержит

if(NULL == key)
   throw exception("Empty key");

прекрасно компилируется в MSVC / VC ++ (2008 (но когда я пробую это на g ++ (4.4.3), я получаю

)
no matching functions for calls to std::exception::exception(const char&) 

Я получил это на работу:

if (NULL == key)
{
   std::string   estr   ("Empty key");
   throw exception("Empty key");
}

Но это просто ужасно.

Это привело меня к другим ошибкам:

std::string   estr   ("");
if (NULL == key)
{
   estr = "Empty key";
   throw exception("Empty key");
}

Понятия не имею, что исключение () ожидает в качестве входных данных. Я нашел что-то, что предлагало бы std :: string или, может быть, std :: string &, но я потерял эту страницу, и миллионы бесполезных страниц, которые я нашел с тех пор, ну, в общем, бесполезны. Иметь все виды информации о классе исключений, использовании исключений, ....

Если не считать моего уродливого исправления, есть ли простой способ сказать g ++, что "это std :: string", а не const char &, и при этом поддерживать VC ++ счастливым? (очевидно, я пытаюсь сделать кросс-компилируемый код из одного источника.)

И в этом отношении, как ID

   throw exception("Empty key");

отличается от

   throw "Empty key";

Спасибо

Wes

Ответы [ 4 ]

3 голосов
/ 28 октября 2011

Строковый литерал всегда имеет тип массива char с размером, достаточно большим, чтобы содержать символы в литерале с нулевым терминатором. Так что "Empty key" имеет тип char[10]. Это может быть неявно преобразовано в char const * или std::string, если требуется.

Ошибка в том, что exception предназначен в качестве базового класса для типов исключений, а не того, что вы создаете напрямую. Вы должны бросить один из типов, определенных в <stdexcept>, таких как std::runtime_error (который может быть создан с использованием строки), или определить свой собственный тип, который наследует std::exception и переопределяет what().

Я предполагаю, что Microsoft добавила нестандартный конструктор в std::exception. Они любят странным образом расширять язык.

2 голосов
/ 28 октября 2011

Избегайте выдачи исключений по типу std::string, поскольку они сами могут генерировать исключение. И в этом случае вы получите Неопределенное поведение .

Бросьте стандартные исключения, определенные в <stdexcept> или иметь свой собственный класс исключений, производный от класса std::exception и выбрасывать его. И переопределить метод what(), чтобы добавить соответствующее описание исключения.

Кроме того, Always throw по значению и catchпо ссылке.

2 голосов
/ 28 октября 2011

std :: exception является базовым классом.

Попробуйте вместо этого выдать std :: runtime_error.

0 голосов
/ 28 октября 2011

"like this" всегда рассматривается как массив const char, в соответствии со стандартом. Это не проблема здесь. Что действительно происходит, так это то, что std::exception имеет только конструктор по умолчанию, еще раз в соответствии со стандартом. Обычно включаются дополнительные конструкторы, принимающие текстовую строку, но этот конструктор работает по-разному в VC ++ и g ++, как показывает ваш пример.

У меня нет документов g ++, но из ваших примеров видно, что он определяет этот нестандартный конструктор как:

explicit exception(const std::string&);

в то время как VC ++ определяет нестандартный конструктор как:

explicit exception(const char*);

...