Будет ли предстоящее добавление модулей в C++ исправлять / облегчать необходимость использования языка pimpl?
Идиома pimpl, насколько я могу судить, скрывает частную реализацию за заранее объявленным именем символа, поэтому она может быть объявлена и использована в частном модуле cpp.
Пример: https://cpppatterns.com/patterns/pimpl.html
Насколько я могу судить, поскольку класс hosint pimpl должен знать о его структуре (размер, aligment), pimpl должен быть косвенным через некоторый указатель.
(или выделенный как блок достаточного размера, затем перемещенный / созданный в место, где он будет переосмыслен при помощи последующего приведения.)
Решает ли это следующая спецификация модулей?
2 ответа
5.2.3 Свойства экспортируемого класса
Иногда раздражающим правилом стандартного C++ является правило контроля доступа, а не видимости. Например, закрытый член класса виден, но не доступен для объектов, не являющихся членами. В частности, любое изменение частного члена класса может вызвать электронную обработку любого модуля перевода, который зависит от определения этого класса, даже если изменение не влияет на достоверность зависимых модулей. Соблазнительно решить эту проблему с модульной системой. Однако наличие двух отдельных наборов правил (видимость и доступность) для учащихся делает нас нежелательным и потенциально плодотворным источником путаницы. Кроме того, мы хотим поддерживать массовую миграцию существующих кодов в модули, чтобы программистам не приходилось беспокоиться о правилах поиска имен членов класса: если вы понимаете эти правила сегодня, то вам не нужно изучать новые правила, когда вы переходите к модулям и делаете это. не нужно беспокоиться о том, как предоставляются классы (через модули или не модули).
Правило 3 В общем, любое свойство класса (например, полнота), которое вычисляется в части декларации экспорта модуля, доступно для импорта модулей как есть.
Поскольку все свойства класса видимы для импортера, любое изменение этих свойств будет видно в импортере. Я не вижу модулей, решающих проблему, которую решает PIMPL.
Согласно этому сообщению в блоге msvc, фрагменты приватных модулей улучшают эргономику pimpl .
module;
#include <memory>
export module m;
struct Impl;
export
class S {
public:
S();
~S();
void do_stuff();
Impl* get() const { return impl.get(); }
private:
std::unique_ptr<Impl> impl;
};
module :private; // Everything beyond this point is not available to importers of 'm'.
struct Impl {
void do_stuff() { }
};
S::S():
impl{ std::make_unique<Impl>() }
{
}
S::~S() { }
void S::do_stuff() {
impl->do_stuff();
}
import m;
int main() {
S s;
s.do_stuff(); // OK.
s.get(); // OK: pointer to incomplete type.
auto impl = *s.get(); // ill-formed: use of undefined type 'Impl'.
}