Мета-рекурсия
От: Шахтер Интернет  
Дата: 03.08.15 12:20
Оценка: 2 (1) +1 -1 :))
Теперь некоторые вещи можно упростить.


template <class UInt,UInt Val=UInt(-1)>
const unsigned BitsOf = (Val>1)? 1+BitsOf<UInt,(Val>>1)> : Val ;


Считаем число бит в беззнаковом типе.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Мета-рекурсия
От: watchmaker  
Дата: 03.08.15 16:32
Оценка: 2 (1)
Здравствуйте, LaptevVV, Вы писали:

LVV>Ну так, может быть, просто разные компилеры используются?


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


Ну и если уж разговор зашёл об компиляторах, то, например, gcc-5.2 компилирует исходный пример, а clang-3.7 выдаёт ошибку. С другой стороны, если пример чуть-чуть переписать пользуясь средствами только C++03, то ситуация может изменится на противоположную: gcc-5.2 теперь находит бесконечную рекурсию, а clang-3.7 выдаёт ответ. Так что тут даже нельзя утверждать что gcc или clang хуже другого справляются с таким кодом — оба иногда сообщают об ошибке (что хорошо), а иногда выдают численный ответ (что на самом деле хуже, так как может замаскировать ошибки в более сложных случаях).

Ну и если уж выбирать способ считать биты, то куда лучше вообще вместо шаблонов взять constexpr-функции — в них правила рекурсии другие, более интуитивно понятные и с ними всё работает во всех компиляторах, удовлетворяющих стандарту:
template <typename UInt>
constexpr unsigned BitsOf(UInt A = -1) {
    return A ? 1 + BitsOf(A >> 1) : 0;
}
Отредактировано 03.08.2015 16:59 watchmaker . Предыдущая версия .
Re: Мета-рекурсия
От: Abyx Россия  
Дата: 03.08.15 19:49
Оценка: +1
Здравствуйте, Шахтер, Вы писали:

Ш>

Ш>template <class UInt,UInt Val=UInt(-1)>
Ш>const unsigned BitsOf = (Val>1)? 1+BitsOf<UInt,(Val>>1)> : Val ;

Ш>


есть же constexpr функции, зачем писать такую нечитаемую штуку
In Zen We Trust
Re[2]: Мета-рекурсия
От: _NN_ www.nemerleweb.com
Дата: 05.08.15 05:31
Оценка: +1
Здравствуйте, ArtDenis, Вы писали:

AD>В дополнении к другим придиркам тоже добавлю что Val=UInt(-1) лучше заменить Val=UInt(~0). Так "более" правильно, т.к. представление отрицательных чисел может быть разным (в случае представления под названием "код со сдвигом" твой код будет выдавать некорректный результат).


В любом случае это не будет работать для знаковых типов потому как "Val>>1" немного не определен
Если хотим поддерживать и знаковые числа нужно вызывать std::make_unsigned .
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Мета-рекурсия
От: B0FEE664  
Дата: 07.08.15 09:48
Оценка: -1
Здравствуйте, ArtDenis, Вы писали:

Ш>>Считаем число бит в беззнаковом типе.


AD>В дополнении к другим придиркам тоже добавлю что Val=UInt(-1) лучше заменить Val=UInt(~0). Так "более" правильно, т.к. представление отрицательных чисел может быть разным (в случае представления под названием "код со сдвигом" твой код будет выдавать некорректный результат).


А чем Val=UInt(~0) лучше Val=UInt(-1)?
UInt(-1) гарантированно даст наибольшее целое влезающие в беззнаковый UInt. А разве можно сказать то же про UInt(~0)?
И каждый день — без права на ошибку...
Re: Мета-рекурсия
От: Vamp Россия  
Дата: 03.08.15 12:40
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Теперь...

Почему "теперь"? С тех пор, как шаблоны придумали, можно.
Да здравствует мыло душистое и веревка пушистая.
Re: Мета-рекурсия
От: watchmaker  
Дата: 03.08.15 12:51
Оценка:
Здравствуйте, Шахтер, Вы писали:


Ш>Считаем число бит в беззнаковом типе.


Не считает:
error: recursive template instantiation exceeded maximum depth
А всё из-за того, что из Bits<T, 0> идёт бесконечно рекурсивный вызов к Bits<T, 0>. Если бы это были обычные функции, то такой рекурсивный вызов не происходил бы из-за условия в тернарном операторе, но для шаблонов соответствующую ветку компилятор всё равно обязан рассмотреть.

Ш>Теперь некоторые вещи можно упростить.

Вот сначала приведи в соответствие со стандартом предыдущий код, а потом сравни простоту и понятность с тем же
std::numeric_limits<UInt>::digits

Ну или с вариантом, завёрнутым в свой шаблон с аналогичным твоему именем:
template <class UInt> constexpr auto BitsOf = std::numeric_limits<UInt>::digits;
Отредактировано 03.08.2015 19:23 watchmaker . Предыдущая версия .
Re[2]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 03.08.15 15:17
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, Шахтер, Вы писали:



Ш>>Считаем число бит в беззнаковом типе.


W>Не считает:
error: recursive template instantiation exceeded maximum depth
А всё из-за того, что из Bits<T, 0> идёт бесконечно рекурсивный вызов к Bits<T, 0>. Если бы это были обычные функции, то такой рекурсивный вызов не происходил бы из-за условия в тернарном операторе, но для шаблонов соответствующую ветку компилятор всё равно обязан рассмотреть.


У меня считает.

Ш>>Теперь некоторые вещи можно упростить.

W>Вот сначала приведи в соответствие со стандартом предыдущий код, а потом сравни простоту и понятность с тем же
template <class UInt> constexpr auto BitsOf = std::numeric_limits<UInt>::digits;
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Мета-рекурсия
От: LaptevVV Россия  
Дата: 03.08.15 16:22
Оценка:
W>Не считает:
error: recursive template instantiation exceeded maximum depth
А всё из-за того, что из Bits<T, 0> идёт бесконечно рекурсивный вызов к Bits<T, 0>. Если бы это были обычные функции, то такой рекурсивный вызов не происходил бы из-за условия в тернарном операторе, но для шаблонов соответствующую ветку компилятор всё равно обязан рассмотреть.

Ну так, может быть, просто разные компилеры используются?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Мета-рекурсия
От: SuhanovSergey  
Дата: 03.08.15 19:20
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Теперь некоторые вещи можно упростить.


Ш>

Ш>template <class UInt,UInt Val=UInt(-1)>
Ш>const unsigned BitsOf = (Val>1)? 1+BitsOf<UInt,(Val>>1)> : Val ;

Ш>


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

template <class T> const unsigned NrOfBits = sizeof(T)*CHAR_BIT;
Re[2]: Мета-рекурсия
От: watchyourinfo Аргентина  
Дата: 03.08.15 20:02
Оценка:
SS>в самом деле, как же мы раньше мучались без мета-рекурсии

SS>
SS>template <class T> const unsigned NrOfBits = sizeof(T)*CHAR_BIT;
SS>


ну а теперь представь себе 80-битовое число (например, с плавающей точкой), которое архитектура требует выравнивать по 16-байтовым границам.
sizeof такого числа будет 16, а не 10.
Re[4]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 03.08.15 21:06
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, LaptevVV, Вы писали:


LVV>>Ну так, может быть, просто разные компилеры используются?


W>Конечно разные. Но смысл не в том, что они разные, а в том, что результат шаблона из первого сообщения неопределён.


Это почему? Я не видел обоснования.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 03.08.15 21:20
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, Шахтер, Вы писали:


Ш>>

Ш>>template <class UInt,UInt Val=UInt(-1)>
Ш>>const unsigned BitsOf = (Val>1)? 1+BitsOf<UInt,(Val>>1)> : Val ;

Ш>>


A>есть же constexpr функции, зачем писать такую нечитаемую штуку


Ну не знаю, я вполне себе читаю.
А constexpr-функции использовать тоже можно, но тогда придётся делать две декларации -- сначала функцию, а потом константу.


template <class UInt>
constexpr unsigned BitsOfFunc(UInt val)
 {
  return (val>1)? 1+BitsOfFunc<UInt>(val>>1) : val ;
 }

template <class UInt,UInt Val=UInt(-1)>
сonst unsigned BitsOf = BitsOfFunc<UInt>(Val) ;
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Мета-рекурсия
От: enji  
Дата: 04.08.15 07:41
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>

Ш>template <class UInt,UInt Val=UInt(-1)>
Ш>const unsigned BitsOf = (Val>1)? 1+BitsOf<UInt,(Val>>1)> : Val ;

Ш>


Круто. Шаблонные константы как-то прошли мимо меня
Re: Мета-рекурсия
От: ArtDenis Россия  
Дата: 05.08.15 05:16
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Считаем число бит в беззнаковом типе.


В дополнении к другим придиркам тоже добавлю что Val=UInt(-1) лучше заменить Val=UInt(~0). Так "более" правильно, т.к. представление отрицательных чисел может быть разным (в случае представления под названием "код со сдвигом" твой код будет выдавать некорректный результат).
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Отредактировано 05.08.2015 5:17 ArtDenis . Предыдущая версия .
Re[2]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 05.08.15 23:53
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Здравствуйте, Шахтер, Вы писали:


Ш>>Считаем число бит в беззнаковом типе.


AD>В дополнении к другим придиркам тоже добавлю что Val=UInt(-1) лучше заменить Val=UInt(~0). Так "более" правильно, т.к. представление отрицательных чисел может быть разным (в случае представления под названием "код со сдвигом" твой код будет выдавать некорректный результат).


Эта конструкция только для беззнаковых чисел. Да и речь не о том. Подсчет числа битов взят только как пример. Речь о рекурсии.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Мета-рекурсия
От: Кодт Россия  
Дата: 06.08.15 12:09
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Теперь некоторые вещи можно упростить.


Грабельки. Не надо такое тащить в продакшен.

http://ideone.com/a83SVo
#include <iostream>
using namespace std;

template<int X> int const num = X==1 ? 0 : 1 + num<X%2 ? X*3+1 : X/2>;
//template<int X> int const ccc = X==0 ? 0 : 1 + ccc<0>; // ошибка: константа ccc<0> явно определена через саму себя
template<int X> int const rec = X==0 ? 0 : 1 + rec<(X ? 0 : 0)>; // поэтому прибегнем к трюку, сделаем вид, что параметр вычисляется
template<int X> int const err = X==0 ? 0 : 1 + err<(X ? X : X)>;

template<int X> int constexpr eee = X==0 ? 0 : 1 + eee<(X ? X : X)>;
template<int X> int const inf = X==0 ? 0 : 1+inf<X-1>;

int n[num<27>];
int r[rec<10>];
//int e[err<10>]; // это не константа времени компиляции, а статическая переменная
//int e[eee<10>]; // зацикливание в constexpr

int main() {
  cout << num<27> << endl; // 111 - честно вычислил рекурсию
  cout << rec<10> << endl; // 1 - честно вычислил рекурсию
  cout << err<10> << endl; // 1 - особенности инициализации статической переменной
//cout << eee<10> << endl; // ошибка: зацикливание в constexpr
//cout << inf<10> << endl; // ошибка: исчерпание глубины рекурсии, inf<-899>
}
Перекуём баги на фичи!
Re[3]: Мета-рекурсия
От: ArtDenis Россия  
Дата: 07.08.15 13:25
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>UInt(-1) гарантированно даст наибольшее целое влезающие в беззнаковый UInt.

С какой это стати?

BFE>А разве можно сказать то же про UInt(~0)?

Сложно сказать. Надо посмотреть что прописано в стандарте насчёт каста (int)~0 к типу unsigned long long. Возможно что и ~0 тоже не катит для данного случая.
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[4]: Мета-рекурсия
От: B0FEE664  
Дата: 07.08.15 13:37
Оценка:
Здравствуйте, ArtDenis, Вы писали:

BFE>>UInt(-1) гарантированно даст наибольшее целое влезающие в беззнаковый UInt.

AD>С какой это стати?

Следствие из 4.7/2 стандарта.

BFE>>А разве можно сказать то же про UInt(~0)?

AD>Сложно сказать.
Вот именно.

AD>Надо посмотреть что прописано в стандарте насчёт каста (int)~0 к типу unsigned long long. Возможно что и ~0 тоже не катит для данного случая.

Прежде чем к касту переходить, надо выяснить что даст ~0.
И каждый день — без права на ошибку...
Re[2]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 07.08.15 15:29
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


Ш>>Теперь некоторые вещи можно упростить.


К>Грабельки. Не надо такое тащить в продакшен.


К>http://ideone.com/a83SVo

К>
К>#include <iostream>
К>using namespace std;

К>template<int X> int const num = X==1 ? 0 : 1 + num<X%2 ? X*3+1 : X/2>;
К>//template<int X> int const ccc = X==0 ? 0 : 1 + ccc<0>; // ошибка: константа ccc<0> явно определена через саму себя
К>template<int X> int const rec = X==0 ? 0 : 1 + rec<(X ? 0 : 0)>; // поэтому прибегнем к трюку, сделаем вид, что параметр вычисляется
К>template<int X> int const err = X==0 ? 0 : 1 + err<(X ? X : X)>;

К>template<int X> int constexpr eee = X==0 ? 0 : 1 + eee<(X ? X : X)>;
К>template<int X> int const inf = X==0 ? 0 : 1+inf<X-1>;

К>int n[num<27>];
К>int r[rec<10>];
К>//int e[err<10>]; // это не константа времени компиляции, а статическая переменная
К>//int e[eee<10>]; // зацикливание в constexpr

К>int main() {
К>  cout << num<27> << endl; // 111 - честно вычислил рекурсию
К>  cout << rec<10> << endl; // 1 - честно вычислил рекурсию
К>  cout << err<10> << endl; // 1 - особенности инициализации статической переменной
К>//cout << eee<10> << endl; // ошибка: зацикливание в constexpr
К>//cout << inf<10> << endl; // ошибка: исчерпание глубины рекурсии, inf<-899>
К>}
К>


Скобки забыл поставить в тернарном операторе. Это так и было задумано?
В целом я так и не понял, чего ты добивался.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Мета-рекурсия
От: Кодт Россия  
Дата: 07.08.15 16:32
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Скобки забыл поставить в тернарном операторе. Это так и было задумано?


Скобки не при чём.

Ш>В целом я так и не понял, чего ты добивался.


Показать, что код слишком стрёмный.

Некоторые константы являются constexpr'ами, другие — статическими переменными константного типа.
Некоторая рекурсия возможна только с трюками.
Бесконечная рекурсия — в некоторых случаях останавливается с трюками, в других не останавливается, хотя должна, в третьих останавливается, хотя не должна.
Перекуём баги на фичи!
Re[4]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 07.08.15 16:44
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


Ш>>Скобки забыл поставить в тернарном операторе. Это так и было задумано?


К>Скобки не при чём.


Вообще-то причем. Тернарный оператор ленивый.

Ш>>В целом я так и не понял, чего ты добивался.


К>Показать, что код слишком стрёмный.


Нууу. Пройдет пару лет, отполируют стандарт, починят компиляторы...
А пока я экспериментирую.
Вот тебе ещё на закуску.


template <unsigned S,unsigned X=S>
const unsigned SqRoot = (X>S/X) ? SqRoot<S,(X+S/X)/2> : X ;
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Мета-рекурсия
От: Кодт Россия  
Дата: 07.08.15 22:07
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>>>Скобки забыл поставить в тернарном операторе. Это так и было задумано?

К>>Скобки не при чём.
Ш>Вообще-то причем. Тернарный оператор ленивый.

У тернарного оператора самый низкий приоритет, скобки там подразумеваются.
template<int X> int const inf = (X==0) ? 0 : (1+inf<X-1>);

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

Почему это может потребоваться. Дело в том, что тип переменной может зависеть от параметра
// метафункция: тип по номеру
template<class T> struct deftype { using type = T; };
template<int N> struct nth : deftype<unsigned char> {};
template<> struct nth<1> : deftype<unsigned long long> {};
template<> struct nth<2> : deftype<unsigned int> {};
template<> struct nth<3> : deftype<unsigned short> {};
template<int N> using result = typename nth<N>::type;

// константа
template<int N> const auto value = result<N>(0);

template<int N> const auto branch = true ? foo<N>() : bar<N>();
// где выражения foo<N>() и bar<N>() каких то разных, но совместимых типов

Я не смог с разбегу придумать показательный пример, чтобы именно приведение к общему типу дало эффект. Не считая sizeof, конечно.

Но в процессе экспериментов получил ICE у компилятора на ideone.com
template<int N> const auto ice = true ? 0 : ice<(N>0 ? N-1 : 0)>;
const auto crash = ice<1>;

http://ideone.com/K9kFX1
prog.cpp: In instantiation of 'const auto ice<1>':
prog.cpp:16:20:   required from here
prog.cpp:15:28: internal compiler error: in tsubst, at cp/pt.c:12126
 template<int N> const auto ice = true ? 0 : ice<(N>0 ? N-1 : 0)>;
                            ^
0x821bd70 tsubst(tree_node*, tree_node*, int, tree_node*)
    ../../src/gcc/cp/pt.c:12126
0x822793a tsubst_decl
    ../../src/gcc/cp/pt.c:11441
0x821b2be tsubst(tree_node*, tree_node*, int, tree_node*)
    ../../src/gcc/cp/pt.c:11934
0x8225b04 tsubst_copy
    ../../src/gcc/cp/pt.c:13081
0x8217f03 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool)
    ../../src/gcc/cp/pt.c:15705
0x8219e48 tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool)
    ../../src/gcc/cp/pt.c:15369
0x821fde7 tsubst_expr
    ../../src/gcc/cp/pt.c:14530
0x821de87 regenerate_decl_from_template
    ../../src/gcc/cp/pt.c:20022
0x821de87 instantiate_decl(tree_node*, int, bool)
    ../../src/gcc/cp/pt.c:20434
0x824c1a3 mark_used(tree_node*, int)
    ../../src/gcc/cp/decl2.c:5032
0x824c53d mark_used(tree_node*)
    ../../src/gcc/cp/decl2.c:5146
0x82b2e24 finish_id_expression(tree_node*, tree_node*, tree_node*, cp_id_kind*, bool, bool, bool*, bool, bool, bool, bool, char const**, unsigned int)
    ../../src/gcc/cp/semantics.c:3582
0x8267a2f cp_parser_primary_expression
    ../../src/gcc/cp/parser.c:4763
0x8268ab4 cp_parser_postfix_expression
    ../../src/gcc/cp/parser.c:6157
0x826acf0 cp_parser_unary_expression
    ../../src/gcc/cp/parser.c:7438
0x826b7f4 cp_parser_binary_expression
    ../../src/gcc/cp/parser.c:8172
0x826bdbb cp_parser_assignment_expression
    ../../src/gcc/cp/parser.c:8430
0x826c1f7 cp_parser_constant_expression
    ../../src/gcc/cp/parser.c:8676
0x8279d76 cp_parser_init_declarator
    ../../src/gcc/cp/parser.c:17270
0x827b0c0 cp_parser_simple_declaration
    ../../src/gcc/cp/parser.c:11607
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <file:///usr/share/doc/gcc-5/README.Bugs> for instructions.
Перекуём баги на фичи!
Re[6]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 08.08.15 10:14
Оценка:
Здравствуйте, Кодт, Вы писали:

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

Вот такой код в С++ законен:


const int C = false ? C+1 : 0 ;


Не вижу причин, почему на шаблонах должно быть иначе.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[7]: Мета-рекурсия
От: Кодт Россия  
Дата: 08.08.15 13:08
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Не вижу причин, почему на шаблонах должно быть иначе.


Значения вычисляются лениво, а типы аргументов тернарного оператора — энергично.
Перекуём баги на фичи!
Re[5]: Мета-рекурсия
От: ArtDenis Россия  
Дата: 09.08.15 09:26
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Прежде чем к касту переходить, надо выяснить что даст ~0.


Кстати, а если вот так: ~UInt(0) ?
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[8]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 09.08.15 20:36
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


Ш>>Не вижу причин, почему на шаблонах должно быть иначе.


К>Значения вычисляются лениво, а типы аргументов тернарного оператора — энергично.


Не вижу никаких проблем с вычислением типов. Тип константы известен --он задекларирован.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[9]: Мета-рекурсия
От: Кодт Россия  
Дата: 10.08.15 15:11
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Не вижу никаких проблем с вычислением типов. Тип константы известен --он задекларирован.


То, что очевидно тебе, не очевидно компилятору.
Заведомо известные типы операндов — это частный случай.
Так же, как заведомо известное значение условия.

Ну и ещё одно ICE на эту тему — http://ideone.com/yxsgWl
То есть, механизм прикольный, но граблистый.
Перекуём баги на фичи!
Re[6]: Мета-рекурсия
От: uzhas Ниоткуда  
Дата: 10.08.15 15:31
Оценка:
Здравствуйте, Кодт, Вы писали:

К>У тернарного оператора самый низкий приоритет, скобки там подразумеваются.


формально, здесь речь не о приоритетах, а об особенности грамматики
Re[7]: Мета-рекурсия
От: Кодт Россия  
Дата: 10.08.15 20:55
Оценка:
Здравствуйте, uzhas, Вы писали:

К>>У тернарного оператора самый низкий приоритет, скобки там подразумеваются.

U>формально, здесь речь не о приоритетах, а об особенности грамматики

Я слово "приоритет" употребил в этом смысле, в грамматическом. То, что в англоязычной cs-школе называется precedence.
Да если бы ветвление стало конфликтовать с подстановкой параметров шаблона или с прочей арифметикой, код просто не скомпилировался бы: конкретно в этом месте двузначность невозможна.
Перекуём баги на фичи!
Re[6]: Мета-рекурсия
От: Кодт Россия  
Дата: 10.08.15 20:56
Оценка:
Здравствуйте, ArtDenis, Вы писали:

BFE>>Прежде чем к касту переходить, надо выяснить что даст ~0.

AD>Кстати, а если вот так: ~UInt(0) ?

~0U и не парить себе мозг
Перекуём баги на фичи!
Re[7]: Мета-рекурсия
От: ArtDenis Россия  
Дата: 11.08.15 02:52
Оценка:
Здравствуйте, Кодт, Вы писали:

К>~0U и не парить себе мозг


Ну уж тогда ~0ULL
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[10]: Мета-рекурсия
От: Шахтер Интернет  
Дата: 13.08.15 15:08
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


Ш>>Не вижу никаких проблем с вычислением типов. Тип константы известен --он задекларирован.


К>То, что очевидно тебе, не очевидно компилятору.

К>Заведомо известные типы операндов — это частный случай.
К>Так же, как заведомо известное значение условия.

К>Ну и ещё одно ICE на эту тему — http://ideone.com/yxsgWl

К>То есть, механизм прикольный, но граблистый.

Всё новое всегда граблистое. Ничего страшного, пройдет несколько лет, отполируют стандарт, доведут компиляторы и всё будет ОК.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.