Open apolukhin opened 3 years ago
yndx-antoshkka, 8 июня 2018, 15:48 Первый пример уже сейчас можно сильно сократить: https://godbolt.org/g/pEm57Y
Второй пример через алиасы не записать https://godbolt.org/g/BixZb4
Донести ваше предложение до стандарта будет безумно трудно, не уверен что игра стоит свечь... Надо прорабоать ситуации, когда struct и implementation различаются по полям/сигнатурам, можно ли объявлять вспомогательные вещи в implementation и какая у них будет область видимости, может ли быть несколько секций implementation в одной еднице трансляции и многое другое.
Вы готовы к трудностям?
Mikhail Shostak, 8 июня 2018, 16:45 yndx-antoshkka, изначально подразумевалось, что implementation будет просто сокращать написание определений. В случае, если программист пытается что-то определить через implementation секцию, чего нет в объявлении, то компилятор будет бросать теже ошибки, что и сейчас, если программист попытается сделать тоже самое с помощью текущего синтаксиса (выше я писал примеры с несколькими ошибками).
Были мысли, что в implementation блоке компилятор может разрешать писать, например, приватные и статические методы. Но это похоже на дополнительную фунциональность, которой сейчас нет в c++, если это стоит добавлять в рамках текущего предложения, то - да, надо подумать и проработать что и как можно реализовать. Это введёт pimpl идиому в язык.
Трудности не проблема
Если отказаться от дополнительного функционала, то поступило предложение сделать синтаксис следующим: namespace class object {...} в таком случае можно исключить введения нового ключевого слова.
Mikhail Shostak, 8 июня 2018, 16:58 Точнее что-то похожее на pimpl
yndx-antoshkka, 13 июня 2018, 12:04 Mikhail Shostak, начать стоит откуда-то отсюда http://eel.is/c++draft/basic.def . Посмотрите, насколько просто будет добавить вашу идею.
Подготовьте примеры покороче, попробуйте оформить вашу идею на английском и закиньте на обсуждение ещё вот сюда: https://groups.google.com/a/isocpp.org/forum/#!forum/std-proposals
Там сидят разработчики компиляторов, они смогут дать поелзную критику о возможности имплементировать данное предложение и о непротиворечивости предложенной грамматики.
Если всё будет ок - то чтоит начать писать предложение, ка кописано вот тут: https://stdcpp.ru/podgotovka-predlozheniya-v-standart-c-instruktsiya
Готов консультировать по любым вопросам :)
WPMGPRoSToTeMa, 20 июня 2018, 18:02 Будет ли в этом смысл если добавят модули?
Виктор Губин, 20 июня 2018, 20:01 Как-то больно ObjectPacal получается (и его NexT/Apple и Borand наследники).
Тогда и with (заменив на using) добавить до кучи :) Что-бы можно было делать что-то вроде
struct Vec3 {
int x,y,z;
};
Vec3 v = {-1,0,1};
using(v) {
x *= 2;
y *= 2;
z *= 2;
}
// foo.hpp
namespace bar {
class Foo {
public:
Foo(const Foo&) = default;
Foo& operator=(const Foo&) = default;
Foo& operator+(const Foo& rhs);
Foo();
~Foo();
void foo();
};
}
// foo.cpp
namespace bar {
using(Foo) {
Foo()
{
// TODO: implement
}
~Foo()
{
// TODO: implement
}
void foo()
{
// TODO: implement
}
// compile time error Foo::foo already defined
static void foo () {
}
Foo& operator+(const Foo& rhs) {
// TODO: implement
return *this;
}
}
Перенос предложения: голоса +9, -1 Автор идеи: Mikhail Shostak
Добавить ключевое слово implementation (или definition) позволяющее определять блок в котором производится реализация структуры или класса для сокращения избыточности кода
Сейчас мы имеем следующий синтаксис для раздельного объявления и определения функций-членов и статических переменных. Выглядит это так:
В .cpp файле получается довольно много повторяющегося кода. С шаблонами лишнего кода становится еще больше. Возможно что-то подобное предлагали, но было бы неплохо иметь механизм в языке, который позволял бы не писать каждый раз 'object::nested_object::'. Использовать его можно примерно так (далее .cpp файл к предыдущему .h файлу):
Идея довольно простая. К сожалению такое нельзя делать используя ключевое слово namespace потому, что компилятор не будет знать что программист хочет определить - глобальную функцию в пространстве имен или же функцию класса. Да и сам класс с пространством имен может конфликтовать. Но это можно сделать с помощью дополнительного ключевого слова. Очевидно, что минус введения нового ключевого слова это то, что старый код, который использует это слово может поломаться. (На самом деле это моё самое большое опосение по этому предложению. Но в c++11 же добавляли новые ключевые слова, возможно со скрипом, но всё же)
Что касается самой конструкции implementation object {}, то она просто говорит компилятору, что всё что определено внутри скобок будет относится к структуре object, в данном случае, которая находится в пространстве имен scope. Таким образом группировка кода позволяет уменьшить избыточность и повысить читабельность кода (Зависит от ситуации конечно. Я давно привык к синтаксису c++, ниже будет пример с шаблонами :P). Т.к. код сгруппирован, то следоватьно внутри блока будет только реализация конкретного класса. Это может поспособствовать организации кода. Возможно кому-то это покажется неудобным, т.к. не получится временно создать глобальную функцию/переменную внутри implementation блока и её придётся помещать в начало. С другой стороны предполагается, что у класса может быть несколько implementation блоков, если требуется вынести часть реализации в другое место или нужно сделать include чего-то прямо в середину файла (мало ли). Сам implementation по-сути работает как некое пространство, внутри которого можно не писать длинные конструкции с путями к реализуемой сущности и/или добавлять параметры шаблона относящиеся к классу для которого мы делаем имплементацию. Не уверен как компиляторы парсят определения функций, но на первый взгляд кажется, что implementaion блок может немного уменьшить время компиляции. Компилятору не нужно будет постоянно парсить типы для нового встреченного определения, он может взять тип из контекста, который у него есть после встречи ключевого слова implementation. Так же отпадает надобность добавлять названия классов в возвращаемые типы, если мы используем тип из нашего класса, ну в общем всё что можно из контекста блоков взять.
Теперь посмотрим на вариант с шаблонами. Есть, например, библиотека gml с математикой для OpenGL на манер GLSL. Там довольно много шаблонов с вынесенной реализацией в .inl файлы. Так же зависимость двух классов друг от друга (возможно это плохая архитектура) может потребовать вынести реализацию шаблонов из класса, чтобы можно было сделать #include другого файла (ну или если банально два небольших шаблонных класса с несколькими функциями находятся в одном файле, и реализацию снизу нужно написать). В общем шаблонный код может выглядеть как-то так:
ту же самую реализацию можно было бы записать следующим образом:
Возможно такой вариант без шаблонных параметров U1 и U2 будет наглядней:
Ну и небольшой пример с c++ в перемешку с objective-c в котором есть подобная конструкция. Язык obj-c позволяет с её помощью делать много других интересных вищей, но это другая история. Так же хотелось бы упоминуть что в obj-c используется ключевое слово @implementation для этих целей. Поэтому поддержка подобного ключего слова для c++ не должна ломать .mm файлы. Возможно в таком случае лучше использовать ключевое слово definition в c++.
На первый взгляд obj-c может показаться страшным, и я знаю c++ программистов, которые сразу вскрикивают услышав слово objective-c и начинают говорить про его ужасный синтаксис. Но проработав 2 года на obj-c и около 5 лет с c++. Моё мнение склоняется к тому, что obj-c выглядит более читабельным чем c++. Хотя, отчасти на это оказывают влияние спецефичные для obj-c механики, которые вряд ли появятся в c++. Моё мнение может быть субъективным. Так что хотелось бы получить объективную и конструктивную критику этого предложения. :)