On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 19.01.13 18:04. Заголовок: Явное противоречие в Стандарте C++ в описании контейнера std::string


Ракссмотрим простой пример.


const int N = 5; 
int a[N] = { 1, 2, 3, 4, 5 };

for ( int i = 0; i < N; i++ ) std::cout << a << std::endl;


В описании индексного оператора в стандарту C++ записано, что


 цитата:
E1[E2] is identical (by definition) to *((E1)+(E2))



Возвращаясь к примеру цикла, его можно переписать следующим образом


 цитата:
for ( int *p = a; p != a + N; ++p ) std::cout << *p << std::endl;



Эти две записи одного и того же цикла эквивалентны.

Теперь обратимся к описанию индексного оператора для стандартного класса std::string в стандарте C++.


 цитата:
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
1 Requires: pos <= size().
2 Returns: *(begin() + pos) if pos < size(). Otherwise, returns a reference to an object of type charT with value charT(), where modifying the object leads to undefined behavior.
3 Throws: Nothing.
4 Complexity: constant time.




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

std::string s( /* some string literal */ ); 

s[s.size()];

Или если строка пустая, то
std::string s; 
s[0];


Более того вы можете написать следующий код

char *p = s.data(); 

while ( *p ) ++p;



То есть вы можетте обращаться к элементу s.data() + s.size() или *( &s[0] + s.size() ), хотя не можете (то есть стандартом не разрешается) изменять этот элемент. То есть согласно стандарту C++ 2011 завершающий символ '\0' теперь является частью хранимой в классе std::string строки.

К тому же никто не запрещает итератор класса std::string определить просто как char *

Итак, вы можете записать

for ( char *p = &s[0]; *p; ++p ) { /* ... */ }


и в то же самое время вы не можете так записать если итератором является char *

for ( std::string::iterator p = s.begin(); *p; ++p ) { /* ... */ }


Хотя эти записи полностью эквивалентны, если итератор в классе std:;string определен как char *

Действительно, мы можем переписать цикл

for ( char *p = &s[0]; *p; ++p ) { /* ... */ }


в виде

for (auto p = s.begin(); *p; ++p ) { /* ... */ }


Чем является p в этом цикле? С одной стороны, это std::string::iterator, с другой стороны, это char *

Получается, что стандарт заявляет, что данное предложение


for ( char *p = &s[0]; *p; ++p ) { /* ... */ }


корректное, и в то же самое время он заявляет, что данное предложение некорректное, так как никто нам не запрещает определеить std::string::iterator! как char *!

Я написал об этом очевидном на мой взгляд противоречии стандарта на форуме по обсуждению стандарта C++. Но, похоже, до членов комитета по стандартизации С++ это доходит со скрипом!

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 1 [только новые]





ссылка на сообщение  Отправлено: 19.01.13 18:49. Заголовок: Фактически, получает..


Фактически, получается, что стандард C++ говорит, что следующий код

std::string s( /* some string literal */ ); 
for ( char *p = &s[0]; *p; ++p ) { /* ... */ }


является корректным кодом, в то время как этот код

std::string s( /* some string literal */ ); 
typedef char *iterator;
for ( iterator p = &s[0]; *p; ++p ) { /* ... */ }


является некорректным кодом, то есть неразрешенным стандартом.


Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 2
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет