trurle: (lem)
trurle ([personal profile] trurle) wrote2009-12-01 05:01 pm

Морские рассказы

C++ подобен морю.

В STL есть класс pair:
#include <utility>
#include <iostream>

using namespace std;

int main()
{
    pair<int, float> p;
    p.first = 3;
    p.second = 4.5;
    cout << p.first << "," << p.second << endl;
}
теперь попробуем у него унаследовать.
#include <utility>
#include <iostream>

using namespace std;

template<typename T> class range : public std::pair<T,T> {
public:
    range(T v) : std::pair<T,T>(v,v) {}
    bool in(T v) { return first <= v && v <= second; }
};
Компилируется? Нет, не компилируется в gcc 4.x, а как компилируется? Вот так:
#include <utility>
#include <iostream>

using namespace std;

template<typename T> class range : public std::pair<T,T> {
public:
    range(T v) : std::pair<T,T>(v,v) {}
    bool in(T v) { return std::pair<T,T>::first <= v && 
                          v <= std::pair<T,T>::second; }
};
Мне это кажется весьма примечательным

[identity profile] vodianoj.livejournal.com 2009-12-01 03:23 pm (UTC)(link)
Баг компилятора или я чего-то недопонял?

[identity profile] trurle.livejournal.com 2009-12-01 03:41 pm (UTC)(link)
И долго стояли в раздумье
Студиозиусы Вагнер и Кох.

и в чем шутка?

[identity profile] gineer.livejournal.com 2009-12-01 03:39 pm (UTC)(link)
все правильно

first и second это не просто свойства,
а параметризированные параметры шаблона
имеют тип в зависимости от того с какими типами шаблон инстанциируется

кроме того, разрешены ведь и обычные first и second
например если вы таковые решите добавить в ваш шаблон, например вот так

template class range : public std::pair
[Error: Irreparable invalid markup ('<t,t>') in entry. Owner must fix manually. Raw contents below.]

все правильно

first и second это не просто свойства,
а параметризированные параметры шаблона
имеют тип в зависимости от того с какими типами шаблон инстанциируется

кроме того, разрешены ведь и обычные first и second
например если вы таковые решите добавить в ваш шаблон, например вот так

template<typename T> class range : public std::pair<T,T> {
int first;
int second;
public:
...

Re: и в чем шутка?

[identity profile] trurle.livejournal.com 2009-12-01 03:40 pm (UTC)(link)
В Вашем примере Вы затеняете поля суперкласса полями наследуемого класса. По прежнему не вполне ясно почему обращение к полям суперкласса должно идти с полным квалификатором.

Re: и в чем шутка?

[identity profile] gineer.livejournal.com 2009-12-01 03:59 pm (UTC)(link)
потому что для шаблонных first и second неизвестен их тип, как я понимаю
С++ у нас ведь сильно типизированный, не так ли?
и ничуть не затеняю, какраз в виду использования полного квалификатора (другое дело, поймет ли это компилятор).

Re: и в чем шутка?

[identity profile] trurle.livejournal.com 2009-12-01 03:59 pm (UTC)(link)
потому что для шаблонных first и second неизвестен их тип, как я понимаю
Известен, разумеется, это тип T.

Re: и в чем шутка?

[identity profile] oblomov-jerusal.livejournal.com 2011-03-10 11:09 am (UTC)(link)
У pair может быть явная специализация
template <> class pair
[Error: Irreparable invalid markup ('<foo,foo>') in entry. Owner must fix manually. Raw contents below.]

У pair может быть явная специализация<pre>
template <> class pair<Foo,Foo> {}</pre> без полей first и second и тогда компиляция range<Foo> повиснет в воздухе.
nine_k: A stream of colors expanding from brain (Default)

Re: и в чем шутка?

[personal profile] nine_k 2009-12-02 02:10 am (UTC)(link)
Это в яве есть type erasure. В C++ вроде бы тип 100% известен.

[identity profile] pilpilon.livejournal.com 2009-12-01 03:51 pm (UTC)(link)
на солярисе 10 студия, компилируется.

#include
#include

using namespace std;

template class range : public std::pair
[Error: Irreparable invalid markup ('<t,t>') in entry. Owner must fix manually. Raw contents below.]

на солярисе 10 студия, компилируется.
<code>
#include <utility>
#include <iostream>

using namespace std;

template<typename T> class range : public std::pair<T,T> {
public:
range(T v) : std::pair<T,T>(v,v) {}
bool in(T v) { return first <= v && v <= second; }
};

int main()
{
range<int> A(5);
std::cout << A.first<< std::endl;
A.second = 100;
if ( A.in(10))
{
std::cout << A.second<< std::endl;

}

return 0;}

</code>
~/cpp > CC p.cxx
~/cpp > ./a.out
5
100

[identity profile] ak-47.livejournal.com 2009-12-01 04:27 pm (UTC)(link)

Раз он в море закинул невод...

[identity profile] ak-47.livejournal.com 2009-12-01 04:25 pm (UTC)(link)
first и second это dependent names. Для dependent names правила lookup при name resolution имеют нюансы. (См. об этом в священных книгах п. 14.6.2/3). В частности, если базовый класс зависит от параметров темплейта (а в данном примере он зависит), то unqualified name в теле наследника не будет по умолчанию разыскиваться в базовом классе.

Как уже отметили некоторые постеры, многие компалеры по доброте душевной ослабляют это требование и находят имя, даже если оно в базовом классе. Но по Стандарту требуется fully qualified имя. Пример из 14.6.2/3:
typedef double A;
template<class T> class B {
    typedef int A;
};

template<class T> struct X : B<T> {
    A a;  // a has type double
};

Re: Раз он в море закинул невод...

[identity profile] trurle.livejournal.com 2009-12-01 04:37 pm (UTC)(link)
Думаете, скоро священные книги приобретут формат Талмуда: посередине исходный текст, узкой колонкой, вокруг комментарии и дискуссии вокруг комментариев.

Re: Раз он в море закинул невод...

[identity profile] ak-47.livejournal.com 2009-12-01 04:44 pm (UTC)(link)
В качестве компенсации толкование священных книг станет почётной и уважаемой в обществе профессией.

Письменный и Устный стандарт C++.

[identity profile] trurle.livejournal.com 2009-12-01 04:48 pm (UTC)(link)
Зеленкович провел всю свою юность, изучая Письменный и Устный стандарт C++. Никто лучше него во всей округе не мог изложить на память правила множественного наследования темплейтных классов. Неудивительно что его сваха могла выбирать самые заманчивые брачные предложения...

Re: Письменный и Устный стандарт C++.

[identity profile] ak-47.livejournal.com 2009-12-01 05:06 pm (UTC)(link)
А как красиво Зеленкович рассказывал о виртуальных функциях на еженедельных летучках перед наступлением субботы! Товарищи Зеленковича по отделу мало что понимали в его речах, но все без исключения восхищались им и сходились во мнении что Зеленкович далеко пойдёт.

И тут по округе пролетела весть о том что к старой тёте Малке из бухгалтерии приезжает сын из столицы, кандидат компьютерных наук. С женой и дочкой. Попроведовать, отдохнуть...

Женился или срезал?

[identity profile] trurle.livejournal.com 2009-12-01 05:10 pm (UTC)(link)
Там дальше сюжет шолом-алейчемовский/балшевис-зингеровский или шукшинский?

Re: Женился или срезал?

[identity profile] ak-47.livejournal.com 2009-12-01 05:21 pm (UTC)(link)
Сам не знаю. Направо - красивые, налево - умные. Боюсь разорваться. :)
stas: (Default)

[personal profile] stas 2009-12-01 09:18 pm (UTC)(link)
А this-> не пойдет?

[identity profile] cmm.livejournal.com 2009-12-02 12:28 pm (UTC)(link)
неспортивно!