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] 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:
...

[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: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
};

stas: (Default)

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