Re[3]: Определение конструируемости объекта заданного типа.
От: Кодт Россия  
Дата: 19.07.06 07:54
Оценка: 2 (1)
Здравствуйте, Went, Вы писали:

W>Усовершенствую библиотеку рефлексии свою я. Для фабрик классов нужно это.

W>Класс может быть инстанцируемым по типу, а может и не быть. Может быть клонируем, а может и не быть. Получается 4 разных случая. Хотелось бы чтобы компилер сам выбирал нужное решение, а для тех классов, которые не клонируются или не инстанцируются, делал заглушки, которые бы вызывали исключения.

Беда в том, что, для того чтобы быть DefaultConstructible (не говоря уже о CopyConstructible), должны соблюдаться условия:
— нет чисто виртуальных функций
— есть соответствующая сигнатура конструктора (конструктор копирования есть всегда)
— и эта сигнатура доступна (т.е. public)
Так вот, с последним пунктом гарантированы проблемы. В С++ нет возможности проверять доступность, только видимость. А видимость и доступность пенпердикулярны.
Поэтому даже если ты проверишь наличие (в MSVC это можно делать, используя псевдонимы — кажется, __ctor, __cctor), то ничего этим не докажешь.

Раз ты пишешь рефлексию, то может быть, проще всего было бы прямо в классе декларировать его роли.
class MyClass : REFLECTION(MyClass, reflectDefaultConstructible) { ..... };

и затем статик-ассертом проверять, не задекларировано ли чего лишнего. (Можно по умолчанию декларировать как запрет, так и разрешение — в зависимости от того, что чаще встречается).
Заодно получаешь возможность вручную блокировать ту-или-иную-конструируемость у классов.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re: Определение конструируемости объекта заданного типа.
От: Шебеко Евгений  
Дата: 19.07.06 09:40
Оценка: 2 (1)
W>Как узнать на этапе компиляции (а-ля boost::type_traits):
W>1. Конструируем ли объект по умолчанию? То есть он не абстрактен, у него есть конструктор по умолчанию и он публичный.
W>2. Конструируем ли объект копированием? То есть он не абстрактен и его конструктор копии (не опрерато присваивания) публичный.
W>В бусте вроде именно такого нет. Хелп плиз
Похоже что никак.
В бусте это вроде есть в type-traits но там говориться что мол требуется
специальная поддержка компилятора. На практике это конечно не работает.

Через SFINAE у меня тоже не получилось. Именно по причине того, что нельзя разрулить public\private.

Лично я остановился на том что ввёл свой type-traits по умолчанию все типы конструируемы,
а если где-то не собираются делаю явную специализацию.
На практике не конструируемых классов, которые надо регистрировать не так и много оказалось.


Типа того:
  template<class T>
  struct default_constructable
  {
    static const bool value=true;
  };

  //В месте регистрации конкретного класса
  template<>
  struct default_constructable<SomeNotConstructableType>
  {
    static const bool value=false;
  };
Определение конструируемости объекта заданного типа.
От: Went  
Дата: 19.07.06 07:12
Оценка:
Как узнать на этапе компиляции (а-ля boost::type_traits):
1. Конструируем ли объект по умолчанию? То есть он не абстрактен, у него есть конструктор по умолчанию и он публичный.
2. Конструируем ли объект копированием? То есть он не абстрактен и его конструктор копии (не опрерато присваивания) публичный.
В бусте вроде именно такого нет. Хелп плиз
Re: Определение конструируемости объекта заданного типа.
От: Кодт Россия  
Дата: 19.07.06 07:21
Оценка:
Здравствуйте, Went, Вы писали:

W>Как узнать на этапе компиляции (а-ля boost::type_traits):

W>1. Конструируем ли объект по умолчанию? То есть он не абстрактен, у него есть конструктор по умолчанию и он публичный.
W>2. Конструируем ли объект копированием? То есть он не абстрактен и его конструктор копии (не опрерато присваивания) публичный.

Для каких целей нужно?
Чтобы сделать compile-time assert, достаточно так
int const assertDefaultConstructible = sizeof( new T() );
int const assertCopyConstructible = sizeof( new T(*(T*)malloc(0)) ); // или даже new T(*(T*)NULL), но это может спровоцировать варнинг

А чтобы SFINAE... видимо, никак. Но мне и придумать сложно ситуацию, в которой потребовалось бы в зависимости от конструируемости идти по разным веткам.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Перекуём баги на фичи!
Re[2]: Определение конструируемости объекта заданного типа.
От: Went  
Дата: 19.07.06 07:30
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Для каких целей нужно?

К>Чтобы сделать compile-time assert, достаточно так
К>
К>int const assertDefaultConstructible = sizeof( new T() );
К>int const assertCopyConstructible = sizeof( new T(*(T*)malloc(0)) ); // или даже new T(*(T*)NULL), но это может спровоцировать варнинг
К>


Нет, compile-time assert не нужен. Нужны разные ветки.

К>А чтобы SFINAE... видимо, никак. Но мне и придумать сложно ситуацию, в которой потребовалось бы в зависимости от конструируемости идти по разным веткам.


Усовершенствую библиотеку рефлексии свою я. Для фабрик классов нужно это.
Класс может быть инстанцируемым по типу, а может и не быть. Может быть клонируем, а может и не быть. Получается 4 разных случая. Хотелось бы чтобы компилер сам выбирал нужное решение, а для тех классов, которые не клонируются или не инстанцируются, делал заглушки, которые бы вызывали исключения.
Re[4]: Определение конструируемости объекта заданного типа.
От: Went  
Дата: 19.07.06 08:13
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Беда в том, что, для того чтобы быть DefaultConstructible (не говоря уже о CopyConstructible), должны соблюдаться условия:

К>- нет чисто виртуальных функций
К>- есть соответствующая сигнатура конструктора (конструктор копирования есть всегда)
К>- и эта сигнатура доступна (т.е. public)
К>Так вот, с последним пунктом гарантированы проблемы. В С++ нет возможности проверять доступность, только видимость. А видимость и доступность пенпердикулярны.
К>Поэтому даже если ты проверишь наличие (в MSVC это можно делать, используя псевдонимы — кажется, __ctor, __cctor), то ничего этим не докажешь.

Да. Почти к этому же я пришел

К>Раз ты пишешь рефлексию, то может быть, проще всего было бы прямо в классе декларировать его роли.

К>
К>class MyClass : REFLECTION(MyClass, reflectDefaultConstructible) { ..... };
К>


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

//h-file
class C
{
};

//some cpp-file
BEGIN_REFLECTION
Class<C>()
  << default_construction()
  << copy_construction()
END_REFLECTION


Вот

К>и затем статик-ассертом проверять, не задекларировано ли чего лишнего. (Можно по умолчанию декларировать как запрет, так и разрешение — в зависимости от того, что чаще встречается).

К>Заодно получаешь возможность вручную блокировать ту-или-иную-конструируемость у классов.

Боюсь, автоопределение все-таки ценнее
Re[2]: Определение конструируемости объекта заданного типа.
От: zaufi Земля  
Дата: 19.07.06 12:21
Оценка:
Здравствуйте, Шебеко Евгений, Вы писали:

лучше поправить это так:

ШЕ>Типа того:

ШЕ>
ШЕ>  template<class T>
ШЕ>  struct default_constructable : public boost::mpl::true_
ШЕ>  {
ШЕ>  };

ШЕ>  //В месте регистрации конкретного класса
ШЕ>  template<>
ШЕ>  struct default_constructable<SomeNotConstructableType> : public boost::mpl::false_
ШЕ>  {
ШЕ>  };

ШЕ>


чтобы это была полноценная метафункция
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.