Loading...

Във форума е въведено ограничение, което позволява на потребителите единствено да разглеждат публикуваните въпроси.

marsp avatar marsp 19 Точки

Judge Assignment 04 - Task 05 Lectures

Здравейте!

Макар, че задачата след известна игра я реших, имам няколко въпроса, на които се надявам някой малко да ме просвети за компилационните грешки и причините им, понеже нещо не успях да разбера с ровене в нета. :D 

1. По принцип вкъщи ползвам основно Visual Studio, понеже ми е по-удобен, а на работа понеже имам пролуки свободно време, ползвам CodeBlocks. Преди да превключа на CodeBlocks, единият ми член на класът (итератора, който трябваше да направя) го бях дефинирал така:

std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<namespace::T>>> begin() const

(Държа да отбележа, че до този код стигнах, след като VS в логът с грешките ми изкара, че този тип му трябва, но в момента вече нямам старият код, който изкарваше въпросният лог) И се компилираше нормално, но после като минах на CodeBlocks даваше следната грешка при компилацията:
"error: '_Tree_const_iterator' in namespace 'std' does not name a template type"

При което след "човъркане" подкарах с:

std::Т<Т>::iterator begin() const // нарочно слагам тук "T" за тип, защото все пак е домашно

Това върви и под компилатора на VS. Та въпросът ми е - каква е причината за тази грешка и какво точно значи? 

2. При дефинирането на оператор "[]" доста време ми отне да разбера, защо точно пищи компилатора с грешката:
"error: 'Т& namespace::operator[](namespace::T&)' must be a nonstatic member function" (пак замених с "Т" и "namespace" за да не подсказвам много). Тук основно "nonstatic" частта ме обърква. Под VS дава, че трябва да е просто "member function".

Въпросът ми е - защо специално за този оператор трябва задължително (или поне аз не открих начин) да бъде дефиниран в класът? Оператори "<<", ">>", "<" без проблем можех да ги дефинирам извън класове (приемайки за агрументи въпросният клас и другото нещо, което му трябва, в сравнение само с нещото което му трябва, ако е дефинирано в самият клас) и после да ги пусна като "friend". И разбира се, в крайна сметка коя е по-добрата практика?

Благодаря предварително! И happy coding на всички! :D


Поздрави!

1
C++ Programming
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки
Best Answer

Здравей,

По първия въпрос, когато видиш нещо, което почва с една или две долни черти, това обикновено означава, че е вътрешен клас/обект/нещо за компилатора, тоест нещо, което не е в стандарта, или поне не е предназначено ти да го ползваш. В случая просто ползваш много конкретен итератор - такъв за еди-какъв-си-set (това TreeSet), какъвто Visual Studio си нарича вътрешната имплементация на set класа. Съответно като го дадеш на компилатора на Code::Blocks, то не знае какво е това.

С две думи, питат те "какво ми трябва, за да стигна от Габрово до София" и ти отговаряш "BMW e46, чипосано", вместо да отговориш "превозно средство", и Code::Blocks, понеже има Хонда, се отказва да ходи до София.

begin() в тази ситуация просто трябва да връща същото нещо, което set.begin() връща - std::set<...>::iterator.

По втория въпрос, отговорът не е особено задоволителен - стандартът казва, че operator[] трябва задължително да е член (различните компилатори изкарват различни грешки ако не е, static, когато става въпрос за оператори, означава overload, който не е член, съответно non-static означава, че трябва да е член). Защо е взето това решение не е съвсем ясно, има теории, че причината е да не можеш да го overload-неш за int и да казваш int a = 4; a[4] = 5; макар че чичо Bjarne Stroustrup казва, че просто било "историческа случайност", един вид така са решили някога, после се е оказало, че няма нужда, ама са забравили да го махнат (или нещо такова).

Поздрави,

Жоро

1
marsp avatar marsp 19 Точки

Супер! Now I’ve seen it all! :D Много благодаря за обясненията сенпай Жоро! :)

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.