powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
25 сообщений из 143, страница 3 из 6
Пятничная шабонная магия
    #39586158
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyт.е. делать свой парсер строки? Ну вот не хотелось этого делать. Строковый поток отлично справляется с этими задачи, кроме одного момента про, собственно, саму строку.
Сейчас пробую сделать через SFINAE.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39590844
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
такой вопрос:

есть иерархия классов, для простоты:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
class A
{
	type_A a_;
public:
	const type_A& Get() const { return a_; }
};

class B : public A
{
	type_B b_;
public:
	const type_B& Get() const { return b_; }
};

class C : public B
{
	type_C c_;
public:
	const type_C& Get() const { return c_; }
};



на самом деле это один класс-шаблон, я расписал в иерархию, чтобы было нагляднее
вопрос: есть ли способ написать метод Get, чтобы оно работало, как написано выше? Чтобы возвращал значение то, которое запрашивается? Именно через возвращаемое значение. Имя должно метода должно быть одинаковое (потому что это один класс).
Через шаблонный метод у меня не получилось, потому что при несовпадении типа метода-шаблона(TE) и класса шаблона(T1) компилятор ругается на несовместимость возвращаемого значения, хотя реально его никогда возвращать не будет:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
template <typename TE> auto Class<T1, TS...>::Get(tstring& name) -> shared_ptr<TE>
{
	if (is_same<TE, T1>::value)
		return value_; // here
	else
		return Class<TS...>::Get<TE>(name);
}
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39591036
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMb,
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
typedef const char type_A;
typedef const short type_B;
typedef const int type_C;

class C 
{
public:

  struct __Get;

private:

  type_A a_ = 0x0a;
  type_B b_ = 0x0b;
  type_C c_ = 0x0c;
  
  friend struct __Get;

public:

  struct __Get
  {
  private:

    operator const C& () const
    {
      register size_t offset = reinterpret_cast<size_t>(&((C*)0)->Get);
      return *reinterpret_cast<const C*>((size_t)this - offset);
    }

  public:

    operator type_A& () const
    {
      return ((const C&)*this).a_;
    }
    
    operator type_B& () const
    {
      return ((const C&)*this).b_;
    }

    operator type_C& () const
    {
      return ((const C&)*this).c_;
    }
    
  }
  Get;
};

#pragma argsused
int __cdecl main(int argc, char* argv[])
{
  C c;
  type_A& i = c.Get;
  type_B& j = c.Get;
  type_C& k = c.Get;
  .
  .
  .
  return 0;
}
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39591404
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rdb_dev, интересная идея, спасибо. Я так понял, что даже без структуры Get, просто с кастами оно тоже работать будет?
Но вот typedef у меня не получится применить, так как набор типов в объекте заранее неизвестен, это шаблон, на каждом объекте набор типов определяется параметрами шаблона. Но вот с кастами надо попробовать, спасибо.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39612660
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
((C*)0)->Get


UB
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39623679
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно как-то в качестве параметра шаблона использовать формулу?

что-то типа
Код: plaintext
1.
2.
3.
4.
temlate<typename F> int Do (int a, int b)
{
return F(a, b);
}



А без лябмд?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39623681
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbможно как-то в качестве параметра шаблона использовать формулу?
Можно использовать класс, в котором использовать (статическую) функцию с нужной сигнатурой.
Но вот если у меня F очень плотно используется? Буквально, хочу в одном месте a+b, а в другом a-2*b, например. И таких штук 10-20, не хочется под всё классы городить, и дорого это по производительности.

Ну а с лямбдами-то это можно сделать?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39623792
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbБуквально, хочу в одном месте a+b, а в другом a-2*b, например.инлайнами и опциями компилятора у меня таки это получилось
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624328
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbCEMbможно как-то в качестве параметра шаблона использовать формулу?
Можно использовать класс, в котором использовать (статическую) функцию с нужной сигнатурой.
Но вот если у меня F очень плотно используется? Буквально, хочу в одном месте a+b, а в другом a-2*b, например. И таких штук 10-20, не хочется под всё классы городить, и дорого это по производительности.

Ну а с лямбдами-то это можно сделать?

Код: plaintext
1.
2.
3.
4.
5.
6.
template <typename T, typename L>
T do_lambda(T a, T b, L func) {
    return func(a, b);
}

do_lamda(1, 2, [](int a, int b){return (a+b);});
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624412
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owlда, отлично, даже без inline код встраивается без вызова! Жаль только что у меня проект в 2010, там лямбд нету.

Отдельно порадовал оптимизатор, к примеру do_lamda(rand(), 1, ...) сводится в результате к инкременту. Ну и вообще без rand и проверки возвращаемого значения не удалось собрать, так как оптимизатор не видел смысла в этом коде, просто выкидывал его из релиза
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624580
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
Код: plaintext
1.
((C*)0)->Get

UBИ что же тут неопределённого для LE?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624592
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guest
Код: plaintext
1.
((C*)0)->Get

UBИ что же тут неопределённого для LE?Что такое "LE"? Little Endian?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624633
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, да.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624650
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev, не понимаю, при чём тут вообще endianness.
null pointer не указывает ни на какой объект, поэтому возможность получать доступ к data member-у сомнительна.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624720
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_dev, не понимаю, при чём тут вообще endianness.
null pointer не указывает ни на какой объект, поэтому возможность получать доступ к data member-у сомнительна.А где ты видишь доступ к члену экземпляра класса по нулевому указателю?
Код: plaintext
1.
2.
3.
4.
5.
operator const C& () const
{
  register size_t offset = reinterpret_cast<size_t>(&((C*)0)->Get);
  return *reinterpret_cast<const C*>((size_t)this - offset);
}

Это банальный расчёт смещения члена внутри структуры экземпляра класса, чтобы инкапсулированный объект мог получить указатель на инкапсулирующий.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624732
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestrdb_dev, не понимаю, при чём тут вообще endianness.
null pointer не указывает ни на какой объект, поэтому возможность получать доступ к data member-у сомнительна.А где ты видишь доступ к члену экземпляра класса по нулевому указателю?Здесь:
Код: plaintext
1.
((C*)0)->Get


rdb_dev
Код: plaintext
1.
2.
3.
4.
5.
operator const C& () const
{
  register size_t offset = reinterpret_cast<size_t>(&((C*)0)->Get);
  return *reinterpret_cast<const C*>((size_t)this - offset);
}

Это банальный расчёт смещения члена внутри структуры экземпляра класса, чтобы инкапсулированный объект мог получить указатель на инкапсулирующий.Который всего лишь приводит к https://wandbox.org/permlink/uf0utxeaF4023z0u prog.cc:29:58: runtime error: member access within null pointer of type 'C' :D
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624750
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devпропущено...
А где ты видишь доступ к члену экземпляра класса по нулевому указателю?Здесь: [src c++]
((C*)0)->GetЕще раз повторяю - в моём нет доступа к члену объекта по нулевому указателю - нет ни чтения структуры, ни вызова функции. Учите C++ ABI !
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624758
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_deva guestпропущено...
Здесь: [src c++]
((C*)0)->GetЕще раз повторяю - в моём нет доступа к члену объекта по нулевому указателю - нет ни чтения структуры, ни вызова функции. Учите C++ ABI !prog.cc:29:58: runtime error: member access within null pointer of type 'C'
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624768
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
((const C&)*this).a_;


UB
Код: plaintext
1.
((const C&)*this).b_;


UB
Код: plaintext
1.
((const C&)*this).c_;


UB
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624793
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, еще и с перегрузкой операторов приведения типа не знаком?
Собрать на g++ и пройтись отладчиком - не судьба?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624803
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_dev, ой-ой. Изв е ните. Оператор приведения типа же определён.

Который весь сплошь из УГ UB состоит. Даже если заменить
Код: plaintext
1.
reinterpret_cast<size_t>(&((C*)0)->Get)

на offsetof (который до C++17 для данного класса был UB, а теперь "conditionally supported") и он будет supported в данной реализации, то арифметика "указателей" там — останется UB.
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624804
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devСобрать на g++ и пройтись отладчиком - не судьба?Принести сюда цитат из стандарта, которые покажут, что код ­валиден — не судьба?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624812
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest, еще раз - где здесь доступ к члену экземпляра класса (чтение свойства/вызов метода) по нулевому указателю экземпляра?
Код: plaintext
1.
2.
3.
4.
5.
operator const C& () const
{
  register size_t offset = reinterpret_cast<size_t>(&((C*)0)->Get);
  return *reinterpret_cast<const C*>((size_t)this - offset);
}


"&((C*)0)->Get" - это что? Амперсанд (взятие адреса) видим?
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624816
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guestrdb_devСобрать на g++ и пройтись отладчиком - не судьба?Принести сюда цитат из стандарта, которые покажут, что код ­валиден — не судьба?Этот код валиден даже для структур чистого Си. Открывай раздел ABI стандарта и читай!
...
Рейтинг: 0 / 0
Пятничная шабонная магия
    #39624887
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rdb_devОткрывай раздел ABI стандарта и читай!Что-то не найду в http://eel.is/c draft/ раздел "ABI".
...
Рейтинг: 0 / 0
25 сообщений из 143, страница 3 из 6
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пятничная шабонная магия
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]