2014-05-05 4 views
1

Проблема неспособности переслать объявление std :: string и std :: wstring часто обсуждается. Как я понимаю, причина в том, что эти типах typedefing из экземпляра класса шаблона basic_string:forward декларация std :: string и std :: wstring

namespace std { 
    typedef basic_string<char> string; 
    typedef basic_string<wchar_t> wstring; 
} 

И опережающее объявление о ЬурейеМ не допускается языком.

это не было бы лучше для C++ стандарта с использованием наследования вместо ЬурейеГо:

namespace std { 
    class string : public basic_string<char> {}; 
    class wstring : public basic_string<wchar_t> {}; 
} 

Так что, как мы могли бы направить объявить зЬй :: строки и зЬй :: wstring?

+4

Зачем вам нужно переслать-объявить их? '#include ' отлично подходит для любых объявлений. – JAB

+0

Это то, чего я пытаюсь избежать - #include ' – chook

+1

Почему вы пытаетесь избежать' # include'? Существуют и другие способы улучшения скорости компиляции; взгляните на предварительно скомпилированные заголовки. –

ответ

5

не было бы лучше для C++ с использованием стандартного наследования вместо ЬурейеЕ [...]

No.

БППП :: basic_string не означает быть унаследованы в любом форма. Это ограничение позволяет реализовать std :: basic_string, который намного дешевле (быстрее) создавать и уничтожать, поскольку он не имеет таблицы виртуальных функций.

Если вам нужна строка std :: [w], которая будет определена, просто #include.

Редактировать (ответ на комментарий)

Одним из руководящих принципов C++ (и стандартной библиотеки) является «не платят за то, что вы не используете». Это означает, что код написан таким образом, что вы не должны нести затраты времени исполнения для функций, которые вам не нужны.

Создание экземпляра std :: string было бы намного дороже, если бы каждый экземпляр имел виртуальную таблицу (и это создавало бы использование std :: string, запрещающее критически важный для работы код).

Вместо этого std :: string используется как быстрая, безопасная для типов реализация RAII механизма C char*. Точно так же вы не должны пытаться наследовать из std :: vector, list, map, shared_ptr, unique_ptr и т. Д.

Если вам действительно нужен базовый класс строки, подумайте о том, чтобы написать самостоятельно your_namespace::[w]string_base (тривиальная реализация была бы такой, которая инкапсулирует std::[w]string внутренне).

+2

таблица виртуальных функций существует только в том случае, если определена хотя бы одна виртуальная функция. – chook

+0

Это правильно, но поскольку в случае наследования вы _need_ - виртуальный деструктор (чтобы избежать попадания в UB), что позволяет наследовать 'std :: basic_string ', на практике это означает, по крайней мере,« определить класс с виртуальным деструктором ». – utnapistim

+0

> std :: basic_string не наследуется в любой форме. Можете ли вы дать ссылку или объяснение этому? а не «только потому, что» – chook

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