LINUX.ORG.RU

Герб Саттер предлагает добавить в С++ метаклассы

 , ,


1

7

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0707r0.pdf

В свежем пропосале Саттер предлагает добавить в С++ механизм для добавления пользовательских мета-типов. Автор отталкивается от наблюдения, что struct это просто class с public:, а enum class это просто class с константами, и предлагает обобщить этот подход и сделать его доступным разработчику. Вот пример реализации аналога interface из Java :

$class interface
{
    ~interface() noexcept {}
    constexpr {
        compiler.require($interface.variables().empty(),
                         "interfaces may not contain data");
        for (auto f : $interface.functions()) {
            compiler.require(!f.is_copy() && !f.is_move(),
                             "interfaces may not copy or move; consider a"
                             " virtual clone() instead");
            if (!f.has_access ()) f.make_public();
            compiler.require(f.is_public(),
                 "interface functions must be public");
            f.make_pure_virtual();
        }
    }
};
// User code (proposed C++)
interface IShape {
    int area() const ;
    void scale_by(double factor);
};
Лично я не верю, что комитет это пропустит, но сам Саттер не последний человек в комитете и понимает, что предлагает.

Ответ на: комментарий от a1batross

Мне кажется, что кресты больше относятся к «миру», чем оторванные от него Rust, D или с чем вы ещё приходите в тред.

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

Ну и какие-то проекты есть и на D и на расте. Может эти языки нормально и не взлетят, но оторванность от мира - это не про них. D так вообще старался (старается?) быть практичной заменой плюсам.

DarkEld3r ★★★★★
()
Последнее исправление: DarkEld3r (всего исправлений: 1)
Ответ на: комментарий от Aswed

Ты еще библию декларировать начни

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

kawaii_neko ★★★★
()
Ответ на: комментарий от DarkEld3r

Может эти языки нормально и не взлетят

Вот только ты не путай Россию со всем миром. D довольно востребован в этих наших европах. даже со всяких C# сейчас не него кое-где переписывают, не говоря уже о прошловековых крестах с кучей костылей.

anonymous
()
Ответ на: комментарий от DarkEld3r

Я это не исключаю. Полезно чему-то поучиться у других.

a1batross ★★★★★
()
Ответ на: комментарий от kawaii_neko

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

человек который не осилил даже шаблоны, не может отличить run-time reflection от compile-time reflection, но критикует Саттера за метаклассы C++... ЛОР такой ЛОР

clover
()
Ответ на: комментарий от anonymous

Вот только ты не путай Россию со всем миром. D довольно востребован в этих наших европах. даже со всяких C# сейчас не него кое-где переписывают, не говоря уже о прошловековых крестах с кучей костылей.

http://githut.info/

39е место.

Ты хоть по сторонам смотри иногда, а то так и протухнешь, программируя на одном единственном языке)

clover
()
Ответ на: комментарий от clover

человек который не осилил даже шаблоны

Мимо.

run-time reflection от compile-time reflection

Вот прям всю жизнь мечтал вчитываться в крестовысеры наподобие цитат из оп-поста. ОПу, конечно, респект за уважение к Ъ, но я в треде с меткой «вброс» вообще-то хочу в очередной раз выказать омерзение к тому куску говна, который называют «современный C++».

критикует Саттера

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

He joined Microsoft in 2002 as a platform evangelist for Visual C++ .NET

kawaii_neko ★★★★
()
Ответ на: комментарий от anonymous

D довольно востребован в этих наших европах. даже со всяких C# сейчас не него кое-где переписывают, не говоря уже о прошловековых крестах с кучей костылей.

И ты, разумеется, можешь продемонстрировать (хоть где-то) количество вакансий сравнимое с C#? Ну или хотя бы с «прошловековыми крестаmи с кучей костылей»?

DarkEld3r ★★★★★
()
Ответ на: комментарий от clover

http://githut.info/

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

программируя на одном единственном языке)

хер ты угадал, петушок.

anonymous
()
Ответ на: комментарий от anonymous

Или то, что на гитхаб куча Васей слила свои лабы на плюсиках?

Как будто что-то плохое.

DarkEld3r ★★★★★
()
Ответ на: комментарий от umren

Смотря для чего. Если писать компилятор C++ с нуля, или свою реализацию STL, то это одно.

Если использовать C++ в разработке софта, то другое. Тут сложность гораздо меньше, особенно если использовать современный C++, а не «старый добрый Cи» немного разбавленный «Си с классами».

eao197 ★★★★★
()
Ответ на: комментарий от eao197

особенно если использовать современный C++

Это в котором куча boilerplate-кода из-за std::move, std::shared_prt, std::unique_prt, etc. и извращений типа {} вместо () ?

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

куча boilerplate-кода из-за std::move

Сами-то поняли какую херню сморозили?

Ну и да, речь не про Rust, а про отличия C++11/14/17 от C++98/03.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Сами-то поняли какую херню сморозили?

Выдрать одно слово из предложения - красота.

Ну и да, речь не про Rust

Я про него и не упоминал. Вопрос был сугубо про C++. Вы не поверите, но 80% времени я пишу именно на нём. Поэтому всё что с ним связано меня очень интересует.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Выдрать одно слово из предложения - красота.

Ну просто про «бойлерплейт код с std::move» — это уже совсем за гранью. Вероятно, у нас разное понимание термина «бойлерплейт». Могли бы вы пару примерчиков из современного C++ привести, которые бы показывали этот самый «бойлерплейт» с std::move или с std::shared_ptr, или с std::unique_ptr?

eao197 ★★★★★
()
Ответ на: комментарий от eao197
// C++11 без auto
std::unique_ptr<MyClass> v = std::unique_ptr<MyClass>(new MyClass());
// C++11
auto v = std::unique_ptr<MyClass>(new MyClass());
// C++14, для тех, кому повезёт с компилятором
auto v = std::make_unique<MyClass>();

// прямой аналог на rust
let mut v = Box::new(MyClass::new());
// правильный аналог на rust 
let mut v = MyClass::new();

// не спец в D, но:
auto v = MyClass();

Или если у вас «современный C++» - это =>C++17, то вам очень повезло.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Блин, у вас мозги-то вообще есть? Вы вот это в состоянии понять?

Ну и да, речь не про Rust, а про отличия C++11/14/17 от C++98/03.

Вы аналоги этого кода для C++98 сделайте. Посмотрите разницу. И на счет «бойлерплейта» с std::move тему вам раскрыть не удалось.

Ну и тем, у кого есть мозги, но нет возможности использовать C++14, не составляет труда написать:

template<typename T, typename... Args>
std::unique_ptr<T> my_make_unique(Args &&... args) {
  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
...
auto v = my_make_unique<MyClass>(bla-bla-bla);

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

И кстати, еще забыли:

std::unique_ptr<MyClass> v{new MyClass()};
А в D, если MyClass — это ссылочный тип, то, емнип, должно быть так:
auto v = new MyClass();

eao197 ★★★★★
()
Ответ на: комментарий от eao197

посоны, вы чо эта? меритесь у кого поинтер длинее?

anonymous
()
Ответ на: комментарий от eao197

Люди и до C++11 использовали свои умные указатели. Это не о чём не говорит.

И на счет «бойлерплейта» с std::move тему вам раскрыть не удалось.

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

RazrFalcon ★★★★★
()
Ответ на: комментарий от eao197

Красота. В расте, значит, синтаксис ужасный, но писать {}, вместо () - это нормально?

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Люди и до C++11 использовали свои умные указатели. Это не о чём не говорит.

Тогда мне не понятно, к чему претензии к бойлерплейту в C++11/14/17. В современном C++ этого бойлерплейта больше не стало, скорее наоборот.

Опять придираетесь?

Пытаюсь вытянуть из вас хоть что-то осмысленное.

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

Т.е. по вашему мнению вот такой гипотетический код:

myclass::myclass(string data) : data_(&&data) {}
содержал бы меньше бойлерплейта, чем вот такой современный:
myclass::myclass(string data) : data_(move(data)) {}
?

В расте, значит, синтаксис ужасный,

Корявый, по меньшей мере.

но писать {}, вместо () - это нормально?

А в чем проблема? Это одна из фич языка, есть места, где она более чем удобна.

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

// правильный аналог на rust
let mut v = MyClass::new();

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

DarkEld3r ★★★★★
()
Ответ на: комментарий от eao197

чем вот такой современный:

Во-первых, std:: забыли. Во-вторых, мне значки по душе, в отличии от многих.

А в чем проблема?

Выглядит уродски. Но мы же не критикуем язык из-за синтаксиса (сарказм).

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Во-первых, std:: забыли

Во-первых, это принципиально ничего не меняет. Во-вторых, вспомните про существование using namespace (что, например, при работе с std::swap имеет архиважное значение при работе с нормальными компиляторами).

Во-вторых, мне значки по душе, в отличии от многих.

Я так понимаю, что вы считаете, что в варианте с && бойлерплейта таки меньше. Так хочу вас разочаровать: его там одинаковое количество. Ибо принципиален момент необходимости преобразования data к rvalue reference. Это преобразование нужно указывать явно. И без этого явного указания не обойтись. А уж делается ли такое указание через && или через вызов std::move — это уже дело вкуса.

Но вы, по-видимому, из любителей посчитать синтаксический оверхэд (c).

Выглядит уродски. Но мы же не критикуем язык из-за синтаксиса (сарказм).

Тут еще большой вопрос, что выглядит более уродски:

int a(b); // (1)
int a{b}; // (2);
И уродски ли выглядит, например, вот такое:
some_class f() {
  ...
  return {a, b, c};
}

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

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

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

Это вы мощно задвинули, внушаить. Qt-головного мозга в предтерминальной стадии, походу.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Это преобразование нужно указывать явно. И без этого явного указания не обойтись.

И этот человек наезжает на раст из-за его explicit over implicit.

у вас больше желания в очередной раз обосрать C++,

Комитет делает это без меня. Считать плюсы вменяемым языком - это клиника.

RazrFalcon ★★★★★
()
Последнее исправление: RazrFalcon (всего исправлений: 1)
Ответ на: комментарий от eao197

Тут еще большой вопрос, что выглядит более уродски:

int a(b); // (1)
int a{b}; // (2);

Насколько я понимаю (1) может молча потерять информацию на сужающем приведении, в то время как (2) не скомпилируется, так что они вообще-то неэквивалентны.

d_a ★★★★★
()

последний гвоздь в это и без того неюзабельное контрпродуктивное говнище

anonymous
()
Ответ на: комментарий от anonymous

D довольно востребован в этих наших европах. даже со всяких C# сейчас не него кое-где переписывают

пердеж, переписывают на голанге, дэ видел один раз в упорото-нитакомкаквсе-ололошке команде

anonymous
()
Ответ на: комментарий от RazrFalcon

При чём тут Qt?

При том, что в Qt злоупотребляют размещением объектов через new.

А в нормальном C++ объекты зачастую размещают на стеке или в виде полей объектов без new, даже не смотря на то, что компилятор типа не следит за временами жизни.

И этот человек наезжает на раст из-за его explicit over implicit.

Вы с темы-то не уходите, речь шла про boilerplate код в C++11/14/17. По этой теме еще что-то сказать имеете?

Считать плюсы вменяемым языком - это клиника.

Речь шла о том, какова сложность C++, а не «вменяемый ли это язык».

eao197 ★★★★★
()
Ответ на: комментарий от d_a

Более того, (1) в зависимости от b, может трактоваться как декларация функции с именем a и возвращаемым значением типа int. А не как объявление переменной a типа int с начальным значением из b. На эти грабли не так уж и сложно наткнуться.

Тогда как (2) — это однозначно объявление переменной a типа int.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Более того, (1) в зависимости от b, может трактоваться как декларация функции с именем a и возвращаемым значением типа int. А не как объявление переменной a типа int с начальным значением из b. На эти грабли не так уж и сложно наткнуться.

Я и натыкался однажды. Сделал

X x();
и долго чесал репу отчего не вызывается X::X(). Правда в записи int a(b); мне показалось неуместным про это вспоминать, так как между скобками здесь ровно одно значение есть.

d_a ★★★★★
()
Ответ на: комментарий от d_a

ЕМНИП, бывает еще и такое:

struct B {};
struct C {
  C(const B & arg) {...};
};
...
C c(B());
Типа того, что мы создаем экземпляр типа C и в конструктор передаем ему временный экземпляр B с дефолтным значением. А на самом-то деле :)

Вот, можете сами попробовать:

#include <typeinfo>
#include <iostream>

struct B {};
struct C {
	B b_;
	C(const B & b) : b_(b) {}
};

int main() {
	C c(B());
	std::cout << typeid(c).name() << std::endl;
}

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от eao197

А в нормальном C++ объекты зачастую размещают на стеке или в виде полей объектов без new, даже не смотря на то, что компилятор типа не следит за временами жизни.

Если я хочу получить подстроку без копирования, то тут или rc или надежды на лучшее.

речь шла про boilerplate код в C++11/14/17

Речь шла про C++11/14. 17 только во влажных фантазиях.

По этой теме еще что-то сказать имеете?

Я уже привёл пример.

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

Если я хочу получить подстроку без копирования, то тут или rc или надежды на лучшее.

В огороде бузина, в Киеве дядька. Подстроки здесь откуда взялись?

Речь шла про C++11/14.

Ну, OK. Примеры бойлерплейта по сравнению с C++98/03 таки будут?

17 только во влажных фантазиях.

Да полноте дебилизм демонстрировать. Драфт уже зафиксирован. Изрядная часть C++17 уже доступна в gcc-7.1 и clang-4.0.

Я уже привёл пример.

Если вы про примеры отсюда: Герб Саттер предлагает добавить в С++ метаклассы (комментарий), то они демонстрируют лишь уровень вашего умственного развития, а не бойлерплейта в C++.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Да, славно конечно :) Мне кстати typeinfo не надо, у меня vim-rtags типы и так выводит по кнопочке через clang:

SymbolName: C c(B (*)())
Kind: FunctionDecl
Type: C (B (*)()) => C (B (*)())
SymbolLength: 1
Range: 57:1-57:9
Linkage: External
Container
Usr: c:@F@c#*F$@S@B#
sizeof: 1
Alignment: 4

d_a ★★★★★
()
Ответ на: комментарий от d_a

Ну вот это один из маленьких примерчиков того, как современный C++ делает обычное программирование на C++ проще, чем во времена C++98/03.

Хотя uniform initialization syntax получился не без своих темных мест. Так что голову на плечах все равно нужно иметь.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Хотя uniform initialization syntax получился не без своих темных мест. Так что голову на плечах все равно нужно иметь.

А какие? Я знаю только что очевидное auto x{y}; примерно в 99.99% выведет x не в то, что надо (в std::initializer_list<>).

d_a ★★★★★
()
Ответ на: комментарий от d_a

А какие?

Самый простой:

std::vector<int> v1(20, 1);
std::vector<int> v2{20, 1};
v1 — это вектор из 20 единичек, тогда как в v2 всего два элемента (20 и 1).

Еще временами неприятно то, что в std::initializer_list значения константные и нельзя для них делать move.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Действительно, я теперь вспомнил, что там что-то мутное накручено с приоритетами конструкторов, если у класса есть конструктор с std::initializer_list, то использоваться будет только он, а другой уже дёрнуть нельзя, кроме как круглыми скобочками. (Ну или я не разобрался.)

d_a ★★★★★
()
Ответ на: комментарий от eao197

Подстроки здесь откуда взялись?
Компилятор типа не следит за временами жизни.

Отсюда. Нужно следить, чтобы строка и подстрока были валидными. Раст эту задачу решает на уровне языка.

Примеры бойлерплейта по сравнению с C++98/03 таки будут?

Повторяю. Уже.

Изрядная часть C++17 уже доступна в gcc-7.1 и clang-4.0.

Ага. То есть давайте сравнивать с C++17, который еще не реализован. Круто, чё. Ну и в большинстве дистров только на 5-ку перешли.

Если вы про примеры отсюда

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

RazrFalcon ★★★★★
()
Ответ на: комментарий от eao197

причина использоваться фигурных скобок в initializer lists на самом деле проще: в круглых скобках невозможно отличить выражение от списка, либо вызов конструктора от списка.

(1,2,3) это на самом деле просто 3, т.к. оператор запятая по дефолту возвращает выражение после запятой. а {1,2,3} - похоже на инициализацию массивов.

не умеет комплятор в libastral поэтому приходится так. плюс у нас просто нет других скобочек на клавиатуре. вот эти три вида скобок []{}() это всё что имеем. интересно, можно ли сделать язык в котором обведенный скобками текст можно комбинацией клавиш подкрасить и цветом придать тексту некий понятный компилятору смысл?

ckotinko ☆☆☆
()
Ответ на: комментарий от RazrFalcon

Отсюда. Нужно следить, чтобы строка и подстрока были валидными. Раст эту задачу решает на уровне языка.

Я рад за Rust, но это вообще не имеет отношения к тому, чтобы размещать объекты в C++ в динамической памяти. В каких-то местах вполне будет достаточно иметь:

std::array<char, 128> data;
utility::string_view substr{data, 10};
даже не смотря на то, что компилятор ни за чем не следит.

Так что смысл этого вашего комментария: Герб Саттер предлагает добавить в С++ метаклассы (комментарий) все еще остается неясным.

Повторяю. Уже.

Хде? Это вы про тот бред с инциализациями для unique_ptr и использованием move? Так вам уже все объяснили, что вы обосраслись.

Еще примеры?

То есть давайте сравнивать с C++17, который еще не реализован.

Забейте на C++17, вы в все равно дуб-дубом в нем. Покажите пример бойлерплейта в C++11 или C++14.

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

Ну так покажите, сколько кода вы бы написали в C++03. Ведь весь новый бойлерплейт сразу же будет виден.

eao197 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.