Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/9: Рейтинг темы: голосов - 9, средняя оценка - 4.78
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
1

Перевести на стандартный С++

03.06.2015, 13:19. Показов 1734. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class TActivator;
typedef void (__closure *TTriggerProc)(TActivator *Sender);
struct TRecepient{
      TTriggerProc OnProc;
      TTriggerProc OffProc;
 
};
class TTrigger(){
....
    std::vector<TRecepient> Rcepients;
....
    void On(TActivator *Activator){
           for (int i=0;i<Recepients.size();i++){
                 if (Recepients[i].OnProc) Recepients[i].OnProc(Activator);
          }
     void Off(TActivator *Activator){
           for (int i=0;i<Recepients.size();i++){
                 if (Recepients[i].OffProc) Recepients[i].OffProc(Activator);
          }
}
т.е. какой аналог __closure (if any) у MSVC++ 13 и других C++ компиляторов?

Добавлено через 48 минут
приделал стандартный костыль из DOS-эпохи:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class TActivator;
typedef void (*TTriggerProc)(void *Object,TActivator *Sender);
struct TRecepient{
      void *Object
      TTriggerProc OnProc;
      TTriggerProc OffProc;
 
};
class TTrigger(){
....
    std::vector<TRecepient> Rcepients;
....
    void On(TActivator *Activator){
           for (int i=0;i<Recepients.size();i++){
                 if (Recepients[i].OnProc) Recepients[i].OnProc(Recepients[i].Object,Activator);
          }
     }
     void Off(TActivator *Activator){
           for (int i=0;i<Recepients.size();i++){
                 if (Recepients[i].OffProc) Recepients[i].OffProc(Recepients[i],Activator);
          }
      }
}
Работать будет 100%, если методы назначать внимательно. Есть ли другие способы или MSVC и все остальные отстали от жизни лет на 20?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.06.2015, 13:19
Ответы с готовыми решениями:

Перевести фиолетовый (105, 62, 151) из RGB в HSB, уменьшить яркость в 2 раза и перевести обратно
Помогите пожалуйста! Перевести фиолетовый (105, 62, 151) из RGB в HSB, уменьшить яркость в 2 раза...

Не стандартный xml
Добрый день! Есть xml файл (прилагаю архив). Его структура нестандартная. Порекомендуйте метод...

Не стандартный 2d массив
Всем привет! Не подскажите, можно ли сделать такой массив, как на картинке? Я понимаю, что можно...

Стандартный конвейер
Здравствуйте,форумчане) работаю с шейдерами посредство glew.h. С помощью функции:...

26
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
03.06.2015, 13:36 2
1) std::function, std::bind?
2) Али boost::signals, али что-то подобное из других библиотек?
3) Али ваш "костыль"(который таки не костыль , а минимальная реализация), али ваш "костыль" расширенный в свой велосипед, копирующий поведение (1) или (2) пунктов.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
03.06.2015, 13:45  [ТС] 3
Цитата Сообщение от Nosey Посмотреть сообщение
1) std::function, std::bind?
2) Али boost::signals, али что-то подобное из других библиотек?
Ну вопрос собственно не в раздаче многим получателям, что тривиально, а вот в таком:
C++
1
2
3
4
5
6
7
8
9
10
11
12
typedef void (__closure *TTriggerProc)(TActivator *Sender);
class Foo{
        void On(TActivator *Sender);
        void Off(TActivator *Sender);
}
void main(){
      Foo Bar;
      TTriggerProc OnProc=Bar.On;
      TTriggerProc OffProc=Bar.Off;
      OnProc(nullptr);
      OffProc(nullptr);
}
Либо такие присваивания (OnProc=Bar.On; ) обрабатываются компилятором либо он отстал от жизни лет на 20.
0
шКодер самоучка
2227 / 1921 / 927
Регистрация: 09.10.2013
Сообщений: 4,262
Записей в блоге: 7
03.06.2015, 13:48 4
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <functional>
 
//....
typedef std::function<void(TActivator*)> TTriggerProc;
//...
class Object {
public:
    void func(TActivator*);
//...
};
using namespace std::placeholders;
Object* o;
TTriggerProc f1 = std::bind(&Object::func, o, _1);
TTriggerProc f2 = [o](TActivator* x)->void {
    //...
    o->func(x);
};
http://www.cplusplus.com/reference/functional/
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
03.06.2015, 14:14  [ТС] 5
Цитата Сообщение от Nosey Посмотреть сообщение
Али ваш "костыль"(который таки не костыль , а минимальная реализация)
А костыль он потому что позволяет перепутать связку объект->метод при назначении.

Добавлено через 9 минут
Цитата Сообщение от Cra3y Посмотреть сообщение
копирующий поведение (1) или (2) пунктов.
поскольку присутствуют задержки в передаче сигналов (имеется в виду OnDelay и OffDelay от изменения состояния входа, повязанные на внешний таймер) при всем богатстве выбора другой альтернативы нет как велосипедить, да и велосипед проще получается чем если велосипедить оборачивая std или boost.

Добавлено через 8 минут
Цитата Сообщение от Cra3y Посмотреть сообщение
Object::func
Та не это не то. надо не функции класса, а функции экземпляра подвязывать, в том числе виртуальные. т.е. внутря __closure аналогичны
C++
1
2
3
4
struct __closure{
   void *Data;
   void *Code;
}
Ну а за соблюдением сигнатур Code при присваивании и преобразованием Foo(Args...) в Foo.Code(Foo.Data,Args); следит компилятор.
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
03.06.2015, 14:19 6
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А костыль он потому что позволяет перепутать связку объект->метод при назначении.
Ну, тогда можно и так перепутать:
C++
1
2
3
4
5
6
7
8
void main(){
      Foo Bar;
      Foo Bar2;
      TTriggerProc OnProc=Bar.On;
      TTriggerProc OffProc=Bar2.Off;
      OnProc(nullptr);
      OffProc(nullptr);
}
Я к тому что иначе и не выдет

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
поскольку присутствуют задержки в передаче сигналов (имеется в виду OnDelay и OffDelay от изменения состояния входа, повязанные на внешний таймер) при всем богатстве выбора другой альтернативы нет как велосипедить, да и велосипед проще получается чем если велосипедить оборачивая std или boost.
В бусте хороший оверхед присутствует, ибо он как раз предоставляет возможность
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
в раздаче многим получателям,
, предоставляет инструмент слежения за подписчиками.
А вот стл - это просто синтаксическая плюшка, с нулевым оверхедом, делающая в конце концов ровно тоже, что и ваш "костыль", и так же требуещее от вас следить за всем.

Cra3y, Собственно привёл пример современного обработчика от стл.

Добавлено через 2 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну а за соблюдением сигнатур Code при присваивании и преобразованием Foo(Args...) в Foo.Code(Foo.Data,Args); следит компилятор.
В стандартной реализации стл за этим следит std::bind(<function>, <object>) возвращающий соответствующий функтор.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
03.06.2015, 14:29  [ТС] 7
Цитата Сообщение от Nosey Посмотреть сообщение
Ну, тогда можно и так перепутать:
Ну как минимум не даст одному Code сунуть Data от другого который вообще из другой иерархии ветки приемников. На крайняк в сеттере можно проверить чтобы Data была одна и та же у обоих обработчиков, что кстати тоже может быть не всегда нужно, особенно если придется (пока до такого изврата еще не дошло) привязывать на on и off разные вложенные классы одного получателя.

Добавлено через 5 минут
Цитата Сообщение от Nosey Посмотреть сообщение
В бусте хороший оверхед присутствует, ибо он как раз предоставляет возможность
Та тут как раз не в оверхеде дело, а скажем в том чтобы к примеру закрытие двери началось после OffDelay секунд после того как выключится входной сенсор присутствия (нажатия на половицу).
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
03.06.2015, 14:36 8
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну как минимум не даст одному Code сунуть Data от другого который вообще из другой иерархии ветки приемников.
Если у них один тип, то конечно даст, и от этого ни как не защититься.
Если разные, то практически ни одна реализация не даст такого сделать.
В общем, я не понимю этой строчки

Но
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
На крайняк в сеттере можно проверить чтобы Data была одна и та же у обоих обработчиков, что кстати тоже может быть не всегда нужно, особенно если придется (пока до такого изврата еще не дошло) привязывать на on и off разные вложенные классы одного получателя.
коли у вас всё так серьёзно, может это и не просто обработчик какой-то? И самое время взглянуть вот сюда: https://ru.wikipedia.org/wiki/... 0%B8%D1%8F

Добавлено через 2 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Та тут как раз не в оверхеде дело, а скажем в том чтобы к примеру закрытие двери началось после OffDelay секунд после того как выключится входной сенсор присутствия (нажатия на половицу).
Ну если вы пишете такую клёвую штуку, то точно, стоит сначала обдумать архитектуру как следует, не надёясь на __closure.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
03.06.2015, 14:38  [ТС] 9
Цитата Сообщение от Nosey Посмотреть сообщение
Cra3y, Собственно привёл пример современного обработчика от стл.
Та отож. Собственно тот геморрой о котором лет 20 назад забыли с появлением __closure.
0
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
03.06.2015, 14:38 10
И касательно обработчиков, я вам советую посмотреть либо в сторону буста, либо написать свой велосипед с контролем времени жизни подписчика. Иначе будет очень туго.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
03.06.2015, 15:38  [ТС] 11
Цитата Сообщение от Nosey Посмотреть сообщение
Ну если вы пишете такую клёвую штуку, то точно, стоит сначала обдумать архитектуру как следует, не надёясь на __closure.
Та нет, таки стоит скинуть ту часть в которой обязаловка MSVC (именно потому и не подходит __closure и остальные прелести bcc), и делать дальнейшее развитие уже с использованием всех языковых средств bcc.

Добавлено через 2 минуты
Цитата Сообщение от Nosey Посмотреть сообщение
либо написать свой велосипед с контролем времени жизни подписчика
Он уже есть. И не только времени но и активности (подвязка на источник таймера в состоянии ожидания и т.п./отвязка после передачи сигнала и т.п.).

Добавлено через 24 минуты
Цитата Сообщение от Nosey Посмотреть сообщение
стоит сначала обдумать архитектуру как следует,
А архитектура простая как гвоздь. Сенсор-триггер-подписчик. При этом триггер порожден от подписчика. Подписчик помнит всех к кому подписался, и из деструктора уведомляет. Ну а учитывая что к примеру дверь из модели никуда не денется, только с самой моделью... то уведомляет на всякий случай. деться могут активаторы поэтому и вынесены отдельно и дергают сенсоры по Id в общем списке, который берут из карты. Вобщем получается набор из которого делается любое каскадирование сигнала. При этом все просто как божий день. За исключением неумения std::vector найти или удалить элемент по значению элемента (быстрее дописать соответствующий метод чем в хелпе найти что его нет).

Добавлено через 30 минут
Цитата Сообщение от Nosey Посмотреть сообщение
В общем, я не понимю этой строчки
TTrigerProc Foo=Bar.On;
компилятор засунет в Foo.Data Bar, а в Foo.Code то что у Bar в VMT соответсвует On.
т.е. к примеру
C++
1
2
3
4
5
6
7
8
9
10
11
class A{
        AOn(TActivator *Activator);
};
class B{
        BOn(TActivator *Activator);
};
A a;
B b;
TTrigger Proc=a.Aon; // будет работать;
Proc=b.Bon;//тоже будет;
Proc=b.Aon;  //ошибка будет.
и никаким образом (кроме костыля c получением адреса и переписыванием указателей в самой структуре __closure) нельзя получить чтобы closure указывал на метод не того класса которого у него объект.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.06.2015, 17:17 12
Цитата Сообщение от Nosey Посмотреть сообщение
2) Али boost::signals, али что-то подобное из других библиотек?
C++
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
64
#include <iostream>
#include <boost/signals2.hpp>
#include <boost/bind.hpp>
 
class Archivator
{
   public:
     Archivator(const std::string& name):name_(name){};
     std::string name()const {return name_;}
     
   private:
     std::string name_;    
};
 
enum class State{ on,off };
 
class Recepient
{
  public:
     Recepient(const std::string& name):name_(name){};
     
     void onArchivatorStateChanged(Archivator* archivator,State state)
     {
       std::cout<<name_<<" "
                <<archivator->name()<<" "
                <<(state==State::on?"on":"off")<<std::endl; 
     }
   
   private:
     std::string name_;       
};
 
class Trigger
{
   public:
     boost::signals2::signal<void(Archivator*,State)> onChangeState;      
 
     void changeState(Archivator* archivator,State state)
     {
       onChangeState(archivator,state);
     }
};
//----------------------------------------------------------
int main()
{
Archivator a1("a1"); 
Archivator a2("a2");
 
Recepient r1("r1");
Recepient r2("r2");
 
Trigger t;
// Подписка
t.onChangeState.connect(boost::bind(&Recepient::onArchivatorStateChanged,r1,_1,_2));
t.onChangeState.connect(boost::bind(&Recepient::onArchivatorStateChanged,r2,_1,_2));
// Вызов события/сигнала
t.changeState(&a1,State::on);
t.changeState(&a2,State::on);
 
t.changeState(&a1,State::off);
 
return 0;
}
//----------------------------------------------------------
Вывод:
r1 a1 on
r2 a1 on
r1 a2 on
r2 a2 on
r1 a1 off
r2 a1 off
1
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
01.07.2015, 16:57  [ТС] 13
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef std::function<void(TCharacter * Character)> TTriggerProc;
class TTrigger : public TControlledObject {
...
void AddReceiver(TControlledObject* Object, TTriggerProc OnProc,
            TTriggerProc OffProc);
...
}
TDoor::TDoor()      
    {
                 //...
        Trigger->AddReceiver(this, [this](TCharacter * aCharacter)->void {this->Open(aCharacter);}, 
                                                      [this](TCharacter * aCharacter)->void{this->Close(aCharacter);});
    };
Ругается матом что не может сгенерировать шаблоны. Ругаются что Qt что Builder, причем каждый по своему.
Qt:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xrefwrap:283: ошибка: C2064: term does not evaluate to a function taking 1 arguments
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2015, 17:06 14
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
C:\Program Files (x86)
Ну Builder вероятно не работает по тому что лямбды не поддерживает поэтому лучше без лямбд boost::function+boost::bind.
В MSVC хз чего не работает, вероятно лямбда не правильно записана, я их не применяю поэтому ничего не могу сказать.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
01.07.2015, 17:30  [ТС] 15
Цитата Сообщение от Avazart Посмотреть сообщение
Ну Builder вероятно не работает по тому что лямбды не поддерживает поэтому лучше без лямбд
Билдер тоже не может шаблон сгенерировать. ему похоже __closure лямбда приснилась и он ее в шаблон вместо void* где то пихает.

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

Добавлено через 9 минут
Цитата Сообщение от Avazart Посмотреть сообщение
поэтому лучше без лямбд boost::function+boost::bind
Да еще такой вопрос. А NULL вместо нее передать можно как вместо __closure а потом перед вызовом на этот NULL проверить?
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2015, 17:34 16
Какой еще нул? Там есть метод проверка на валидность function смотри доку.

C++
1
2
if(!f.empty()) 
  f();
Для очистки:
C++
1
f.сlear();
C++
1
f= 0;
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
01.07.2015, 17:46  [ТС] 17
Цитата Сообщение от Avazart Посмотреть сообщение
Ну Builder вероятно не работает по тому что лямбды не поддерживает
подправил запись лямбды, Builder прожевал и прекрасно работает.
C++
1
2
Trigger->AddReceiver(this, [this](TCharacter * aCharacter)->{this->Open(aCharacter);}, 
                                                      [this](TCharacter * aCharacter)->{this->Close(aCharacter);});
а Qt не хочет...
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.07.2015, 17:51 18

Не по теме:

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
подправил запись лямбды, Builder прожевал и прекрасно работает.
Под x64 ....



Добавлено через 54 секунды
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а Qt не хочет...
А Qt тут при чем.... если компилятор MSVC2012.
Но я чет сомневаюсь что причина в компиляторе, скорее где-то в коде накосячил.
0
2063 / 1542 / 168
Регистрация: 14.12.2014
Сообщений: 13,402
02.07.2015, 08:07  [ТС] 19
Цитата Сообщение от Avazart Посмотреть сообщение
Но я чет сомневаюсь что причина в компиляторе, скорее где-то в коде накосячил
Ну билдер его же как то компилирует. clang который.

Добавлено через 11 минут
Причем что самое интересное вызовов подобных в коде 6 а ошибок по этому поводу 4

Добавлено через 6 часов 20 минут

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Под x64 ....
Ну под x86 билдер хоть как то компилит. а Qt вообще говорит - иди лесом ищи компилятор который not found хотя в списке компиляторов есть (MSVC++ 12 (x86))



Добавлено через 7 часов 35 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void DoorOpen(TControlledObject *Object, TCharacter *Activator){
        ((TDoor *)Object)->Open(Activator);
    }
    void DoorClose(TControlledObject *Object, TCharacter *Activator){
        ((TDoor *)Object)->Close(Activator);
    }
 
    TDoor::TDoor(TGame * aGame, T3DCoordf aPosition, T3DCoordf aDimensions,
        T3DCoordf aDirection, float aSpeed, TMesh * aMesh)
        : TControlledObject(aGame, aPosition, aDimensions, aDirection, 0, aMesh)
    {
            //......
                Trigger->AddReceiver(this, DoorOpen,DoorClose);
    };
Ну в общем прикрутил в результате вот такой "лямбда"-костыль досовских времен. Qt+MSVC однако...
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
02.07.2015, 09:43 20
Цитата Сообщение от Nosey Посмотреть сообщение
2) Али boost::signals, али что-то подобное из других библиотек?
у мну так:


C++
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
struct example: receive<some>
{
    void ReadMessage(const some&){ ... }
};
 
int main()
{
    // в момент своего создания, 
    // автоматически подписывается на получение сообщений
    example obj; 
 
    // запустит obj.ReadMessage(some_object);
    // для всех объектов-подписчиков,
    // у которых есть метод ReadMessage(some)
    // или аналогичные, но работающие с ссылками.
    SendMessage( some(param) );
 
    // проверки на ошибки, 
    // детект необходимых функций-членов,
    // регистрация класса-подписчика,
    // генерация транспортной магистрали 
    // происходит автоматически
    // времени компиляции
 
    // что делает статическую систему сообщений
    // чрезвычайно быстрой по скорости работы в рантайме
 
    // в рантайме есть только одна возможная ошибка
    // от которой не существует защиты:
    // если объект будет перемещен по новому адресу
    // при помощи memcpy, например
    // то сообщение будет отправленно по невалидному адресу
 
    // std::function, boost::signals - все  они страдают от этой проблемы
}
обратите внимание:
по смыслу действия это похоже на boost::signals
но в отличие от него, не требуется сохранять коннекшены.
не требуется выполнять никаких явных действий по подписке/отписке.

код не загромождается само-собой разумеющимися деталями.

(на самом деле существует возможность
явно подписаться/отписаться/указать метод.
но как я и ожидал,
на практике они оказались невостребованными)
0
02.07.2015, 09:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.07.2015, 09:43
Помогаю со студенческими работами здесь

Стандартный калькулятор
Ребята помогите пожалуйста сделать стандартный калькулятор на windows

Стандартный джойстик
В Unity в папке Standard Assets (Mobile) для управления есть стандартный двухкнопочный джойстик...

Не стандартный ЧПУ
Переношу сайт из yii с сохранением ссылок. В общем есть post type &quot;remont, сейчас ЧПУ в wordpress...

Стандартный Поиск
Windows7, Lotus клиент 8.5.2 FP2 Standard не могу найти, где выводится значок поиска, добавляю его...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru