Russian Qt Forum
Март 29, 2024, 17:07 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4   Вниз
  Печать  
Автор Тема: c++ новый стандарт (комитет)  (Прочитано 22727 раз)
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #15 : Декабрь 09, 2019, 14:45 »

В соседней теме - жаркие споры типа "нужно писать так чтобы по объявлению было ясно, а не уповать ..". А что понятно по объявлению template ?
Код
C++ (Qt)
template<class T>
T Lerp( const T & a, const T & b, double w );
 
Не было бы популярного Lerp - и информации ноль. Ну часто call оператор (та еще мудистика), а так - только "уповать". И разбираться (что выжирает время).

Жаркие споры идут про типы параметров, чтобы было понятно, что можно передавать в функцию, а что нельзя. И чтобы минимизировать возможные ошибки, которые могут совершить разработчики при передаче аргументов в функцию. А что именно делает функция - это другой вопрос. Тут нужно либо искусство ёмко и понятно называть сущности, либо писать для них документацию.

Читал про SFINAE, ну смысл примерно понял, но выглядит громоздко и неуклюже. Было бы гораздо лучше иметь какое-то формальное "описание" для template (наподобие описания класса).

Формальное описание для шаблонов, как уже сказали, это концепты.

И кстати: а кто такая "рефлексия"?  Улыбающийся

Это такая бабка у подъезда, которая всё про всех знает Улыбающийся. Рефлексия (программирование). Только там больше про рефлексию времени выполнения, а C++ ожидают рефлексию времени компиляции. Ищите "c++ reflection ts".
Записан

Пока сам не сделаешь...
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #16 : Декабрь 09, 2019, 14:52 »

Конкретно мне необходимо во время компиляции генерировать некоторые типы данных на основе других типов данных.
Интерфейс новых типов зависит от интерфейса базовых.

Рефлексии достаточно, или хотелось бы метаклассов Улыбающийся?
Записан

Пока сам не сделаешь...
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #17 : Декабрь 09, 2019, 14:57 »

Рефлексии достаточно, или хотелось бы метаклассов Улыбающийся?

Метаклассов тоже хотелось бы, даже сильно)). Но они не отменяют необходимость рефлексии.
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #18 : Декабрь 09, 2019, 15:13 »


Конкретно мне необходимо во время компиляции генерировать некоторые типы данных на основе других типов данных.
Интерфейс новых типов зависит от интерфейса базовых.

Что вы так сложно все объясняете. Сложность нужна когда человек погрузился.
Рефлексия  - moc в Qt


Также я бы предложил иметь возможность использования шаблонизации для квалификаторов и типов ссылок.
То есть, если имеется несколько методов

Код
C++ (Qt)
class X
{
   void method () &;
   void method () const &;
   void method () volatile &;
   void method () const volatile &;
   void method () &&;
   void method () const &&;
   void method () volatile &&;
   void method () const volatile &&;
};
 

с одинаковой реализацией, чтобы их можно было группировать в виде одного или нескольких методов, например,

Код
C++ (Qt)
class X
{
   void method () mutable, const &, volatile &&, const volatile; // как-нибудь так
   // или по-другому
};
 


Та елки палки. Что это такое?
Так же с ума можно сойти.
Я вообще ничего не понял.

То один this на null проверяет, второй пишет    
 void method () &&;

Либо я тупой, либо разверните каждую функцию. Извините, но язык программирования важен в деталях.
И если у вас столько функций, а вы хотите! всего лишь превратить их в одну, зачем их столько писать?
Ведь смысл в каждой это оптимизация? Да и, как писалось выше, const это декларативная вещь, типа как private в классе, редко влияет на оптимизацию.
« Последнее редактирование: Декабрь 09, 2019, 15:17 от Azazello » Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #19 : Декабрь 09, 2019, 15:38 »

Скажем, вместо пары итераторов binary_search будет принимать "RandomAccessContainer" (ну или какие там требования нужны).
По сути, синтаксический сахар для SFINAE, но открывает кучу всяких возможностей (типа std::sort НАКОНЕЦ-ТО будет принимать один параметр, а не два).

Ну да, ну да.....
Два параметра передавать жопа полная. Тут согласен. Я бы вообще психанул и им не пользовался. Но самое прикольное от НАКОНЕЦ ТО. Улыбающийся)))) Ту уж позвольте над вами поиздеваться Улыбающийся

Хех. На своем опыте мне никогда не приходилось сортировать контейнер не полностью, но с чего бы терять универсальность, даже если это 0.1% пользователей?
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3257


Просмотр профиля
« Ответ #20 : Декабрь 09, 2019, 16:20 »

Ну да, ну да.....
Два параметра передавать жопа полная. Тут согласен. Я бы вообще психанул и им не пользовался. Но самое прикольное от НАКОНЕЦ ТО. Улыбающийся)))) Ту уж позвольте над вами поиздеваться Улыбающийся

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


На самом деле, там "внутри" так и будет пара итераторов, завернутая в range, удовлетворяющий определенному концепту (то, что сейчас сделано через iterator traits).
То есть будет ошибка не вида "итератор шаблонного класса от десятка шаблонных аргументов пофейлил вот эту проверку" а будет "рэнж не удовлетворяет концепту Имярек".
Я пока не разбирался как матчатся рэнжи на std::string_view/std::span (то есть, когда я делаю std::views::all от вектора, я получаю std::span или что?), но в любом случае, там есть куча методов манипуляции с view, проблема что они не все документированы. Но вот пример из доки
Код:
   std::vector<int> v{0,1,2,3,4,5};
    for(int n : std::views::all(v) | std::views::take(2) ) {
        std::cout << n << ' ';
    }
печатает "0 1"
То есть получить "кусок" первоначального вектора будет не проблема, вопрос только в синтаксисе

Ну то есть прелесть рэнжей в манипуляциях с самими рэнжами (это что-то типа генераторов в питоне но не совсем), а сортировка от одного параметра это приятный бонус, а не основная фича.
« Последнее редактирование: Декабрь 09, 2019, 16:23 от Авварон » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #21 : Декабрь 09, 2019, 16:23 »

void method () &&;

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

Ну да, ну да.....
Два параметра передавать жопа полная. Тут согласен. Я бы вообще психанул и им не пользовался. Но самое прикольное от НАКОНЕЦ ТО. Улыбающийся)))) Ту уж позвольте над вами поиздеваться Улыбающийся

Надо мной тогда тоже можете поиздеваться Улыбающийся. Я тоже рад, что в алгоритмы можно будет меньше параметров передавать, а не begin/end'ы постоянно писать.
Записан

Пока сам не сделаешь...
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #22 : Декабрь 09, 2019, 16:39 »


 void method () &&;


Тогда уж я точно не понимаю. Объсните что-куда перемещается.
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #23 : Декабрь 09, 2019, 16:50 »

void method () &&;

Тогда уж я точно не понимаю. Объсните что-куда перемещается.

ref-qualified member functions.
Записан

Пока сам не сделаешь...
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #24 : Декабрь 09, 2019, 16:58 »

void method () &&;

Тогда уж я точно не понимаю. Объсните что-куда перемещается.

ref-qualified member functions.


Прочитал. И что куда перемещается? Без шуток.
 void method () &&;

В чем смысл void? что куда он перемещает?
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #25 : Декабрь 09, 2019, 17:02 »

Либо я тупой, либо разверните каждую функцию. Извините, но язык программирования важен в деталях.
И если у вас столько функций, а вы хотите! всего лишь превратить их в одну, зачем их столько писать?
Ведь смысл в каждой это оптимизация? Да и, как писалось выше, const это декларативная вещь, типа как private в классе, редко влияет на оптимизацию.

 Смеющийся Смеющийся Смеющийся Смеющийся Смеющийся

Рефлексия может реализоваться не только дополнительной кодогенерацией типа moc Qt.

Например, захотелось нам реализовать для типа Type обертку Wrapper, да такую, чтобы Wrapper ничем внешне не отличался от Type.
Область применения таких оберток оставим вне рамок данного поста).

Заранее неизвестно, какой набор методов содержит Type. Язык позволяет реализовать 8 вариантов одинаковых методов (модификаторы * типы ссылок).
Таким образом необходимо рефлексировать все возможные варианты при их наличии. Не буду останавливаться на вопросах чем отличаются друг от друга модификаторы или ссылки, так как это относится к базовым знаниям языка.

Пример результата рефлексии,

Код
C++ (Qt)
 
class Type
{
   // ...
   iterator begin ();
   const_iterator begin () const;
   // ...
};
 
// развернутая рефлексия для Wrapper, код достаточно страшный на вид)
 
class Wrapper
{
   Type m_type; // например, Wrapper содержит Type по значению
   // ...
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) & { /*additional code*/; return m_type.begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const & { /*additional code*/; return m_type.begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) volatile & { /*additional code*/; return m_type.begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const volatile & { /*additional code*/; return m_type.begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) && { /*additional code*/; return static_cast<Type && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const && { /*additional code*/; return static_cast<Type && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) volatile && { /*additional code*/; return static_cast<Type && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const volatile && { /*additional code*/; return static_cast<Type && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   // ...
};
 
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #26 : Декабрь 09, 2019, 17:06 »

Прочитал. И что куда перемещается? Без шуток.
 void method () &&;

В чем смысл void? что куда он перемещает?

Здесь нет никакого перемещения. Просто описывается интерфейс для rvalue ссылки

Код
C++ (Qt)
 
struct Type
{
   void method () && { ::std::cout << "Hello rvalue method " << ::std::endl; }
};
 
void main ()
{
   Type().method(); // ОК
 
   Type value;
   value.method(); // ERROR
   ::std::move( value ).method(); // OK
}
 
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #27 : Декабрь 09, 2019, 17:09 »

Прочитал. И что куда перемещается? Без шуток.
 void method () &&;

В чем смысл void? что куда он перемещает?

По ссылке же пример есть, и как раз с void. Он не перемещает, а метод выбирается в зависимости от того, вызывается он для lvalue или rvalue ссылки на объект.
Записан

Пока сам не сделаешь...
ssoft
Программист
*****
Offline Offline

Сообщений: 574


Просмотр профиля
« Ответ #28 : Декабрь 09, 2019, 17:15 »

Пример результата рефлексии,

... второй раз запостил и все-равно наврал))
правильно будет

Код
C++ (Qt)
 
class Type
{
   // ...
   iterator begin ();
   const_iterator begin () const;
   // ...
};
 
// развернутая рефлексия для Wrapper, код достаточно страшный на вид)
 
class Wrapper
{
   Type m_type; // например, Wrapper содержит Type по значению
   // ...
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) & { /*additional code*/; return static_cast< Type & >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const & { /*additional code*/; return static_cast< Type const & >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) volatile & { /*additional code*/; return static_cast< Type volatile & >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const volatile & { /*additional code*/; return static_cast< Type const volatile & >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) && { /*additional code*/; return static_cast<Type && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const && { /*additional code*/; return static_cast<Type const && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) volatile && { /*additional code*/; return static_cast<Type volatile && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
   decltype(auto) begin ( _Arguments && ... arguments ) const volatile && { /*additional code*/; return static_cast<Type const volatile && >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }
 
   // ...
};
 

сходство рефлективных методов налицо).
Записан
Azazello
Самовар
**
Offline Offline

Сообщений: 103


Просмотр профиля
« Ответ #29 : Декабрь 09, 2019, 17:31 »

Прочитал. И что куда перемещается? Без шуток.
 void method () &&;

В чем смысл void? что куда он перемещает?

Здесь нет никакого перемещения. Просто описывается интерфейс для rvalue ссылки

Код
C++ (Qt)
 
struct Type
{
   void method () && { ::std::cout << "Hello rvalue method " << ::std::endl; }
};
 
void main ()
{
   Type().method(); // ОК
 
   Type value;
   value.method(); // ERROR
   ::std::move( value ).method(); // OK
}
 

Что Ок.
В том то и дело, что это бессмысленно. Не смыслва в void method() &&. Он по фунционалу ничем не будет отличаться от void method().  Такие вещи, демонстрирующие, что что-то компилируется, но не объясняющие суть, просто введут в ступор человека ,не знакомым с данной технологией. Многие побоятся спросить (чтобы не показаться глупыми), будут читать выше наведенные документации, где тоже std::cout << "Hello rvalue method " << ::std::endl; Честно, меня ввело в ступор - все говорят что нужно, но не говорят зачем. Затем дают заднюю....

Может где то это конструкция и нужна теоретически, но вы же не объяснили в чем смысл void method() &&

Как по мне, ваш пример для понимания "должен" выглядеть так.

Код:
class Test {
public:
    Test(): mData(100,100) {}

    std::vector<int> clear() &&  { return std::move(mData); }

private:
    std::vector<int> mData;
};

int main() {
    Test t;
    std::vector<int> r = std::move(t).clear(); //move data
}

Поэтому для меня многие описанные выше методы не имеют смысла и начинаешь задуматся не о теме разговора, а о том, что "что то упустил". Откуда я знаю, приводите вы реальные вещи или "а это для примера". Вон Igors для примера this c null сравнивал, так заклевали Улыбающийся

Код:
template < typename ... _Arguments,  typename = ::std::enable_if_t< подходящий метод для _Type существует > >
    decltype(auto) begin ( _Arguments && ... arguments ) & { /*additional code*/; return static_cast< Type & >( m_type ).begin( ::std::forward< _Arguments && >( arguments ) ... ); }

Какое все вырвиглазное.............................
Но смысл понятен.

 

« Последнее редактирование: Декабрь 09, 2019, 19:49 от Azazello » Записан
Страниц: 1 [2] 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.24 секунд. Запросов: 22.