2010-12-27 20 views
8

OK, przed wykładaniem mnie na temat używania funkcji variadycznych w stylu C w C++ ... wszystko inne okazało się wymagać przepisania Qt MOC.Funkcje Qt i variadic

Chciałbym wiedzieć, czy możesz mieć "slot" w obiekcie Qt, który pobiera arbitralną ilość/typ argumentów. Chodzi o to, że naprawdę chcę móc generować obiekty Qt, które mają sloty arbitralnego podpisu. Ponieważ MOC jest niekompatybilny ze standardowym preprocesingiem i szablonami, nie można tego zrobić za pomocą bezpośredniego podejścia. Ja po prostu wymyślił inny pomysł:

struct funky_base : QObject 
{ 
    Q_OBJECT 
    funky_base(QObject * o = 0); 

public slots: 
    virtual void the_slot(...) = 0; 
}; 

Jeśli jest to możliwe, to, ponieważ można zrobić szablon, który jest podklasą obiektu QObject pochodzącej tak długo, jak nie deklaruje nowy Qt rzeczy w nim, Powinienem być w stanie zaimplementować szablon oparty na szablonach, który pobiera rzeczy o nazwach ... i zamienia je w odpowiednie, oczekiwane typy.

Jeśli tak, jak się z nim połączyć? Czy to działa?

connect(x, SIGNAL(someSignal(int)), y, SLOT(the_slot(...))); 

Jeśli nikt nie próbował niczego to szalony i nie zna się za rękę, tak ja w końcu spróbować to sam ... ale mam nadzieję, że ktoś ma już istniejąca wiedza mogę dotknąć zanim ewentualnie tracę czas na to.


Ta kwestia była próba znalezienia sposobu zaprojektowania klasy „catch-all” bazy na matrycy obiektu, który może przełożyć Qt sygnałów na sygnały statycznych takich jak boost :: signals2 czy tylko podstawowe funkcje. Pomyślałem, że gdybym mógł zbudować slot, który miał szablony variadyczne, mógłbym użyć TMP do zrekonstruowania parametrów z va_args. Odpowiedź na to pytanie polegała właśnie na tym, ale przed wprowadzeniem automatu Qt do gry zadzwoni. Pierwsza rata w serii artykułów na temat jak uczynić całość pokazał mi jak rozwiązać tę część problemu:

http://crazyeddiecpp.blogspot.com/2011/01/quest-for-sane-signals-in-qt-step-1.html

To mój stary lokalizację blogu. Nowe w moim profilu, jeśli chcesz zobaczyć inne dziwne sh1t.

+2

NVM, odpowiedziałem na własne pytanie. Qt oczywiście nie jest w stanie tego zrobić. –

+1

Posiadając niezapisane gniazda, dajesz jedną z podstawowych zalet języka ... bezpieczeństwo podczas kompilacji. –

+2

Frank, szczery, szczery. Qt już to zrobiło. Próbuję odzyskać bezpieczeństwo typu. To była jedna, nieudana próba. Zobacz mój blog na temat ewentualnej historii sukcesu (jest na moim profilu). –

Odpowiedz

2

Wygląda na to, że ludzie wciąż myślą, że to pytanie wciąż wymaga odpowiedzi, ponieważ kilka tygodni po tym, jak go o to poprosiłem, a następnie odpowiedziałem na nie, ludzie wciąż publikują swoje odpowiedzi. Sądzę więc, że muszę wyraźnie podać odpowiedź zamiast obu w samym pytaniu i po raz pierwszy:

Nie można użyć funkcji variadic jako sygnału lub szczeliny w Qt.

Spędziłem dużo czasu i wysiłku, nie tylko rozwiązując problem i udostępniając go, ale wyjaśniając, JAK problem został rozwiązany. Rozważ czytanie, możesz nawet nauczyć się czegoś nowego.

+1

Na SO nie ma problemu, aby odpowiedzieć na własne pytanie;) –

1

Wszystko, aby rozwiązać ten problem, będzie brzydkie, ale nie powinieneś sam wykonywać całego ciężkiego podnoszenia. Możesz użyć boost::any lub boost::variant jako typu argumentu, a następnie rzuć obiekt, aby zawierał potrzebne argumenty (lub użyj wektora dowolnego typu/wariantu).

Możesz również użyć QVariant, ale nie jest tak ładny jak boost :: variant, a na pewno nie jest tak elastyczny (za cenę) jak boost :: any.

(Lub po prostu przepisać Qt z boost :: signals lub wariantem trX ::, ponieważ obecnie żyjemy w XXI w. Również, nie za bardzo szmugować programistów Qt dla stanu sygnałów/slotów - C++ - funkcje, które zwiększają wykorzystanie sygnałów, nie były powszechnie obsługiwane przez kompilatory C++, gdy Trolltech opracował ich implementację sygnału/gniazd).

-1

Należy zauważyć, że "..." konstrukcje nie mogą przyjmować "prawdziwych" obiektów, ponieważ C++ nigdy nie zadał sobie trudu, aby rozszerzyć składnię "...".

To naprawdę dobra wiadomość w twoim przypadku, ponieważ oznacza to, że następująca sugestia może ci pomóc, nie martwiąc się o autodestrukcję obiektów w C++.

Co można zrobić, to stworzyć prosty obiekt, którego konstruktor przyjmuje "...".Przejdzie przez swoje argumenty, zrzucając je do tablicy przydzielanej dynamicznie. Następnie możesz przekazać ten pojedynczy obiekt do gniazda.

Załóżmy, że jesteś leniwą maszynistką i nazwałeś ten obiekt V (dla wariantu lub variadika lub czegoś podobnego). Następnie można wywołać funkcję, która pobiera V tak:

function(V("one", "two", "three", NULL)); 

oczywiście, każdy rozmówca musiałby zbudować V przez strony, które być może nie jest to dokładnie to, co liczyliśmy.

+0

Nie głosowałem na to, ale "nie martwiąc się o autodestrukcję obiektów w C++" jest raczej niebezpiecznym stwierdzeniem. W przeciwnym razie zgodziłbym się w większości. Obiekty C++ z destruktorami powinny być automatycznie niszczone. Brak tego pomija podstawowy mechanizm w języku. – stinky472