среда, 19 марта 2008 г.

X или x в структуре/классе ?

Думали тут с коллегой как автоматически определять какие x,y в структуре (ну т.е. большие или маленькие). Это нужно для написания, например, шаблонной функции определения площади многоугольника - чтобы туда можно было передать точки типа POINT с x,y (в GDI) или Point с X,Y (как в GDI+). На каком-то этапе возник код такого вида:
template<int> struct TT {typedef int type;};
template<class P> bool Check_x(P p, typename TT<sizeof(&P::x)>::type b = 0) { return true; }
template<class P> bool Check_x(P p, typename TT<sizeof(&P::X)>::type b = 0) { return false; }

struct P1 {int x; };
struct P2 {int X; };

int main()
{
P1 p1 = {1};
P2 p2 = {1};

Check_x(p1); // must return true
Check_x(p2); // must return false

return 0;
}
И он не компилируется в Visual Studio (проверено на 2005SP1). Не принимается sizeof в шаблоне, хотя стандарт это позволяет. Баг был послан в Microsoft. Подробнее про баг тут. Кстати сказать, проверка в GNU C++ показала хороший результат - это работает. Зато не сработает код такого вида:
template<class P> bool Check_x(P p, typename TT<&P::x==&P::x>::type b = 0) { return true; }
это, видимо, тоже баг, но уже в g++. Вторая конструкция была как раз использована для обхода проблемы в компиляторе от микрософт (там, правда, возникли другие проблемы).
Кстати в MSVC++ компилируется и такой код:
template<class P> bool Check_x(P p, typename TT<!(&P::x)>::type b = 0) { return true; }
Кто нибудь знает что он означает? По идее должна выдаваться ошибка на этапе компиляции...

Комментировать в ВКонтакте