(. Uwaga:Jak powinno już być jasne, ze znacznikami, to bezwzględnieC++ 03Tak, wiem, to wszystko sprawia, że lambda ból odejdzie (i przynosi nowy rodzaje, założę się), ale jest to system wbudowany, z wersją systemu operacyjnego z lat 90., i powiedziano mi, że powinienem się cieszyć, że mam kompilator C++ 03 (GCC4.1.x, BTW) lub C++ Więc proszę, powstrzymajcie się od publikowania rozwiązań w C++ 11. Nie trzeba go wcierać, naprawdę.
Ponadto, std::bind()
, std::function()
itd. są oczywiście w wersji std::tr1
, ale edytowałemPrefiks, ponieważ uważam, że dodaje do kodu głównie szum.)Jak to zrobić z std :: bind?
Mam pewne coś podobnego do serwera, z którym muszę się zarejestrować i muszę je dostosować, aby wywoływać podobne, ale nieco inne funkcje obiektu. Te funkcje mają różne listy argumentów. Serwer "wie", że i kiedy próbuję zarejestrować funkcję, akceptuje tylko taką z prawidłowym sygnaturą (tak, jak to jest wymagane), w zależności od jakiegoś magicznego znacznika przekazanego jako argument szablonu.
Oto szkic kodu:
// this I just use
class server {
public:
template<unsigned int MagicTag>
bool register_call(typename some_traits_type<MagicTag>::func_type);
};
// this needs to be called from the server
class X {
public:
bool foo();
bool bar(std::string&);
bool baz(int);
};
// this is the glue
class Y {
public:
Y(X& x) : x_(x) {
register_call<MAGIC_FOO>(&Y::foo );
register_call<MAGIC_BAZ>(&Y::bar, _1);
register_call<MAGIC_FBZ>(&Y::baz, _1);
}
private:
X& x_;
template<unsigned int MagicTag, typename Function>
bool register_call(Function function) {
somewhere->register_call<MagicTag>(std::bind(function
, this));
}
template<unsigned int MagicTag, typename Function, typename PlaceHolder1>
bool register_call(Function function, PlaceHolder1 place_holder1) {
somewhere->register_call<MagicTag>(std::bind(function
, this
, place_holder1));
}
int foo() {return x_.foo() ? MAGIC_OK : MAGIC_FAILED;}
int bar(std::string& s) {return x_.bar(s) ? MAGIC_OK : MAGIC_FAILED;}
int baz(int i) {return x_.baz(i) ? MAGIC_OK : MAGIC_FAILED;}
};
To faktycznie działa, ale w rzeczywistości istnieje sposób więcej funkcji i robi to jako żmudnych wysiłków copy'n'paste obraża moje poczucie godności i produkuje śmierdzący kod. Ponieważ wszystkie te funkcje robią dokładnie to samo, z tą różnicą, że są to funkcje, które wywołują i argumenty, które mają, lub nie mają, do przekazania, powinienem być w stanie je spakować w jedną sparametryzowaną funkcję, ukrywając różnice za std::bind()
. W przeciwnym razie zdecydowałem się na pierwsze wykonanie tego dla wszystkich funkcji bez żadnych parametrów (jak w foo()
), co jest przytłaczającą większością.
Więc chciałem trasie wszystkie połączenia z foo()
-jak funkcji w X
przez jedną funkcję Y::call_it
, dokłada żmudny udział:
int call_it(std::function<bool()> f) {return f() ? MAGIC_OK : MAGIC_FAILED;}
i wiązania odpowiedniej funkcji w X
jako argument do niego:
register_call<MAGIC_FOO>(&X::foo); // note the X!
// (this is wrong)
somewhere->register_call<MagicCode>(std::bind(std::bind(&Y::call_it
, this
, function)
, std::ref(x_));
Oczywiście jest to błędne, podobnie jak wszystkie inne moje próby rozwiązania tego problemu. (Gram tylko z std::bind()
przez 10 tygodni, więc proszę o zachowanie mnie). W końcu zagubiłam się w niesamowitym labiryncie zabawnych komunikatów o błędach z szablonowych wnętrzności, które mogą zmusić dorosłego mężczyznę do łez i przez co najmniej roku powinni karmić kurczęcia i jego dalszą rodzinę.
Tak więc przed I kill myself out of sheer frustration i sierotą moje dzieci - jak mogę to zrobić?
Nigdy nie używałem std :: bind. Jak to się ma do spowiedzi. Ale nie chcesz 'register_call (std :: bind (& Y :: call_it, this, std :: bind (ptmf, std :: ref (x_)));'? –
rici
@rici: Tak, oczywiście, masz rację. [Już to widziałem] (http://chat.stackoverflow.com/transcript/10?m=6878122#6878122.) To po prostu, że waliłem głową w ścianę godzin, a to jest po prostu zdezorientowany stan w środku 1001. postaraj się, aby to działało, kiedy zdecydowałem, że muszę o to zapytać. Problem polega jednak na tym, że nie mogę go uruchomić w inny sposób , albo. _Sigh._ – sbi
Chyba dlatego nigdy nie użyłem std :: bind. Metadebugging szablonów jest szalony, albo doprowadza cię do szaleństwa, co jest prawdopodobnie powodem, dla którego wszystkie standardowe implementacje bibliotek są poniżej standardu. Powodzenia! – rici