Как нам реорганизовать С++
Apr. 24th, 2024 12:49 pmПонадобилось мне давеча сделать нечто хитрое с помощью взаимно-рекурсивных классов.
Опуская непринципиальные для обсуждения детали, я написал нечто вроде
#include <iostream>
#include <vector>
struct Foo;
template <typename T> struct BarT { T foo1, foo2; }; // !!!
using Bar = BarT<Foo>; // !!!
struct Foo { std::vector<Bar> bar; };
// Демонстрация, что компилируется и работает
int main() {
Bar bar;
std::cout << sizeof(Foo) << ' ' << sizeof(Bar) << '\n';
}
А теперь внимание, вопрос: какого бы, собственно, рожна нас в XXI веке заставляют прыгать через обруч, вместо того, чтобы просто писать, взамен отмеченного !!!,
struct Bar { Foo foo1, foo2; };
Что мешает компилятору, при виде недоопределенных классов внутри определяемого класса, автоматически делать вид, что это был темплейт?
no subject
Date: 2024-04-24 09:01 pm (UTC)Да это всё Строуструпная ментальность. Толпы людей зависли вот с этой всей ерундой в голове. "Как нам сделать хуже, чем в джаве, сишарпе и котлине? А вот так вот. Чтоб потом можно было показывать сложение матриц в виде просто операции +
Они как на другой планете живут. Ну или, точнее, в другом веке. В двадцатом.
scala> object Z { | case class Pair(a1: Arr, a2: Arr) | case class Arr(ps: List[Pair]) | } object ZТут нужен object Z, чтобы не давать ничему компилироваться, пока не закроем Z.
no subject
Date: 2024-04-24 09:26 pm (UTC)А так-то для
class Arr;
using Z = std::variant< Pair = std::pair< Arr, Arr >, Arr = std::vector< Pair > >
тоже всего лишь небольшой синтаксически-сахарной мелочи (определения алиаса типа внутри параметров темплейта) не хватает.
no subject
Date: 2024-04-24 09:13 pm (UTC)https://github.com/BjarneStroustrup/profiles
no subject
Date: 2024-04-24 09:31 pm (UTC)Профили - это несколько в другую сторону. Я веду речь исключительно об удобстве того, что можно сделать и сегодня.
no subject
Date: 2024-04-24 09:44 pm (UTC)Можно представить себе специальный "профиль" Си++, где такое разрешается.
no subject
Date: 2024-04-24 09:26 pm (UTC)no subject
Date: 2024-04-24 09:34 pm (UTC)Я удивляюсь, что наблюдаемая разница сродни тому, как если бы a+b не компилировалось, а
#define ADD(x,y) x+y
ADD(a,b)
компилировалось.
no subject
Date: 2024-04-24 09:43 pm (UTC)Примитивный пример понятен, а как компилятор будет "автоматически делать вид, что это был темплейт" не столь доступно. Разрешат они это. Дальше на вход поступят посложнее примеры. Неоднозначности применения тимплейта наступят.
no subject
Date: 2024-04-24 10:58 pm (UTC)using оригинальное_имя_класса = уникальное_имя<список_типов>;
no subject
Date: 2024-04-24 10:00 pm (UTC)не защищена от опечаток.
а с template Foo повторено дважды.
no subject
Date: 2024-04-24 10:51 pm (UTC)no subject
Date: 2024-04-24 11:29 pm (UTC)Но что делать с?:
struct Bar { Foo *foo1; };В Си это законная конструкция, например вынесенная в .h
и определений Foo может быть несколько в разных файлах
При шаблонизации будет порождено несколько классов Bar, которых линкер увидит под разными именами
(или под одним, но все равно неопределенность)
no subject
Date: 2024-04-25 01:05 am (UTC)no subject
Date: 2024-04-25 05:58 am (UTC)no subject
Date: 2024-04-25 07:10 am (UTC)