[c++] сколько максимум апмерсэндов подряд может быть в программе?

Serab

Была такая глава в саттере в конце шуточная, а тут я решил вспмонить, но что-то долго не мог, и не гуглилось. А вот сейчас вспомнил. Кому интересно, могут поломать голову :grin:
На самом деле можно начать попроще: с плюсов и минусов.
т.е. надо именно без пробелов подряд, типа ++++i, оно работает всегда, но надо побольше :)
Блин, с плюсами накосячил, тут не максимум, а вообще вопрос: сколько может быть...

Maurog

а я вот такую задачку придумал: придумать пример, когда C-style каст невозможно выразить через C++ касты (static, dynamic, reinterpret) (поведение кастов регламентируется стандартом, а не конкретным компилятором, поэтому примеры, опирающиеся на особенность компилятора неинтересны)

okunek

когда C-style каст невозможно выразить через C++ касты (static, dynamic, reinterpret) (поведение кастов регламентируется стандартом
если поведение кастов регламентируется стандартом, то никогда :grin:

Serab

что-нибудь в шаблончике, когда неизвестно, встроенный тип или класс там с множественным наследованием :)

Maurog

что-нибудь
очень расплывчатый пример :grin:

Serab

ну т.е. вот буквально

template<class F, class T>
T to(const F& from)
{
return (T)from;
}

чтобы так же универсально кастил. т.е. по сути не реализуешь сам универсальный каст :grin:

Maurog

ну т.е. вот буквально
попробую внести внесу ясность в задачу
есть у меня выражение типа
бла1 = (гыгы)бла2
тут "мудрый" заявляется, что C-style deprecated, берет в руки могучие C++ касты.....и не может ничего поделать :shocked:

Serab

ну вот в моем примере что поделаешь?
Бывает что-то подобное и осмысленное, вроде приведения с проверкой попадания в диапазон. А static_cast не даст указатель, например, преобразовать в int.

Maurog

ну вот в моем примере
ищется пример с конкретными типами
пример на понимание особенности работы типов в c++

Serab

ищется пример с конкретными типами
вот, так бы сразу и сказал, это куда интереснее :)

Maurog

так бы сразу и сказал
ну твою задачу тоже можно легко решить вот так, но я же не предлагаю такое, потому что понимаю условие :grin:
вот пропеллерман тоже понял задачу, судя по ответу :grin: :grin: :grin:

Serab

потому что понимаю условие
ну вот это ключевое, а я твое сначала не понял.

Serab

Вот, есть еще приведение к базовому приватному классу.
Но это же ацкий чит, нафига такое делать? Поэтому может и депрекэйтед :)

Maurog

приведение к базовому приватному классу
уже тепло =)
осталось соорудить пример

Dasar

> сколько максимум апмерсэндов подряд может быть в программе?
больше трех не получается
> На самом деле можно начать попроще: с плюсов и минусов.
плюсов и минусов может быть бесконечно большое число

Serab

да я соорудил уже, я ж не гуру, в голове такое компилить не могу :grin:

class A {
public:
A() : x(1) {}
virtual ~A() {}

int x;
};

class C {
public:
C() : y(2) {}
virtual ~C() {}

void g()
{
cout << "C::" << y << endl;
}

int y;
};

class B : private A, private C {
public:
void f()
{
C* p = static_cast<C*>( this );
p->g();
}
};

int main()
{
B b;
((C*)( &b ))->g();

return 0;
}

Serab

плюсов и минусов может быть бесконечно большое число
как сделать нечетное? (это так, для затравки, вопрос-то очень простой)
больше трех не получается
ну ты ведь понимаешь, что если бы ответ был 3, то это бы было не интересно, да и не про C++ ;)

Dasar

как сделать нечетное? (это так, для затравки, вопрос-то очень простой)
перегрузить унарный оператор -
ну ты ведь понимаешь, что если бы ответ был 3, то это бы было не интересно, да и не про C++ ;)
у меня лексер ругается, что ему не нравится второй подряд &&, пока не понимаю как его обойти..

Serab

у меня лексер ругается, что ему не нравится второй подряд &&, пока не понимаю как его обойти..
лексер? А ему не пофигу? Какой компилятор? Я только на gcc, кстати, тестил, но это по стандарту по идее все.

Dasar

лексер? А ему не пофигу? Какой компилятор? Я только на gcc, кстати, тестил, но это по стандарту по идее все.
в ideone работает?

Serab

сработало

Serab

теперь его можно там найти :grin:

Serab

блин, ты меня развел, там же gcc :grin:

Serab

O_O это какие-то C Extensions, они у Саттера не используются, там чистый стандартный Си++. Но с их помощью вроде бы больше все равно не удастся сделать :)

Dasar

лексер? А ему не пофигу?
лексер выдает лексему && вместо двух лексем & & и синтаксис ломается
т.е. вот такое по смыслу должно работать, но не компилится пока пробелы не вставишь:

class Z
{
public:
Z operator & ()
{
return *this;
}
};


int main()
{
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Z();
}

Serab

так это известная фича, лексер жадный, да, такая последовательность всегда разбирается как пары &&, так по смыслу и есть. единственное исключение — это с некоторых пор в шаблонах две закрывающих угловых скобки стали распознаваться.

Serab

ну т.е. три у тебя получилось. и ты понимаешь, что && бинарный, т.е. хочется еще что-то "унарное", начинающееся или заканчивающееся на амперсанды подогнать к &&&. Вот и вопрос, как это сделать.

Dasar

начинающееся или заканчивающееся на амперсанды подогнать к &&&
начинающееся не подойдет - лексер не даст, необходимо заканчивающееся, а мне что-то ничего в голову не приходит, но я еще подумаю.

Dasar

туплю..
что означает запись?

int && x = 12;

ppplva

rvalue reference

Serab

если бы было c++0x, я бы предупредил :)

Serab

начинающееся не подойдет - лексер не даст, необходимо заканчивающееся, а мне что-то ничего в голову не приходит, но я еще подумаю.
ну да! Осталось немного фантазии :) Что может заканчиваться на && ? чистый C++, никаких трюков :)

Serab

ищется пример с конкретными типами
пример на понимание особенности работы типов в c++
кстати, вот все-таки, неужели это желательное поведение? Это же явное нарушение инкапсуляции и "мудрый" бы сказал, что такое делать ай-ай-ай, разве нет?
И почему оно вообще работает, кстати?

Serab

ок, ладно, имхо, это из-за того, что в сях он мог кастить любые указатели, поэтому тут просто так отбирать это не хотят. Но решили сделать, чтобы он достойно работал с классами, а не был как reinterpret_cast. Ня?

zya369

 class C {
public:
bool operator&() { return true;}
};


int main(int argc, char*argv[]) {
C c;
bool i = true &&& c;
cout << i << endl;
return 0;
}

или я недопонял что вы тут обсуждаете?

Serab

надо больше трех :)
и неясно зачем эти извращения, если в Си можно три сделать точно так же :)

zya369

ну вроде же то что асет кнул дает 4
хз правда что там со стандартом
 int main(int argc, char*argv[]) {
c:
bool i = true &&&& c;
cout << i << endl;
return 0;
}

Serab

надо больше 4х :grin:

Dasar

Что может заканчиваться на && ? чистый C++, никаких трюков
хз, сдаюсь. По памяти ничего не вспоминается, в списке постфиксного оператора (или заканчивающегося на) && тоже нет: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B.
значит это не оператор, а какая-то неведомая синтаксическая фигня :) , может быть связанная с типами или функциями - у них зубодробительный синтаксис

Serab

значит это не оператор, а какая-то неведомая синтаксическая фигня
вполне ведомая, ты писал в своей программе выше :)
Вообще, в приват пришло правильное решение от , апплодисменты :D
У него решение даже много лаконичнее моего, пускай кинет ссылку на ideone

zya369

а сколько у него амперсандов?
5 или 6?

Serab

вообще-то тут в треде уже пришли к логическому выводу :) Тут ломают голову над тем, как бы сделать два бинарных оператора подряд, но чтобы можно было сделать сразу три, это сильно. Пять короче :)

Serab

лол, а сделал 6, можно писать саттеру :grin:
Правда это из-за того, что тут в треде задали тон на решения, выходящие за стандарт, адресов меток там нету :) это чисто gcc

procenkotanya

за счёт GNU Extension'а?

Dasar

если совместить предложения и -а, то можно 6 сделать: на ideone - работает, в VS - нет

Serab

ну да, писать никому не стоит, пожалуй :)

procenkotanya

как я понял, тут все заинтересованные уже догадались до решения, но раз уж явно просил: http://ideone.com/veOu8
после подсказки "Что может заканчиваться на &&?" стало совсем просто

zya369

http://ideone.com/sevxw
у меня такое компилится
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

zya369

http://ideone.com/DSU3Q - с 6-ю

Serab

это не стаднарт, обсудили же. Но круто все равно, да :)

apl13

А разве нельзя просто?
class D {
};

class E: D {
};

int main()
{
E d;
(D *)&d;
// static_cast<D *>(&d);
}

Serab

ну типа тут не демонстрируется, что reinterpret_cast может неверный результат давать.
В твоем примере эффект он него такой же, как и от сишного каста.

apl13

А, нужно универсальное средство. :)
О, кстати, правильно ли я определяю:
Определение. Говорят, что тип B наследует типу A, если существует отображение I: B→A, не являющееся ни конструкцией, ни приведением типов, ни функцией, ни оператором. Область видимости I называется областью видимости наследования.
?

Serab

не универсальное средство, а пример, где нельзя выразить сишный каст через плюсовые не прибегая к магии. В твоем примере можно заменить.

apl13

Ну в смысле, универсальное для всех кастов. :)

Serab

а, ну это да, само собой :)
так-то нельзя же сделать static_cast<void*>( 48 )

apl13

        reinterpret_cast<C*>(reinterpret_cast<char *>(&b) + sizeof(A))->g();

:dance2:

Maurog

reinterpret_cast<C*>(reinterpret_cast<char *>(&b) + sizeof(A))->g();
сдвиг баз не регламентирован, поэтому здесь имеем UB
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Empty_Base_...
ТС привел правильный пример, имхо
Оставить комментарий
Имя или ник:
Комментарий: