Qt, és a komplex számok.(qt-creator)

 ( emberk | 2009. október 30., péntek - 13:10 )

Sziasztok!

Érdekes problémába ütköztem. (Vagy én rontok el valamit). Adódott egy olyan munka, amiben sok matek van, gondoltam csinálok hozzá gui-t, mert a 3 soros paraméterláncot kicsit erősnek találtam. Qt-re esett a választásom, mert ebben gyors, és könnyű, a gui készítés.
Eddig magamnak reszeltem ki különböző módszerekkel, a komplex számok kezelését. De gondoltam, hogy minek találjam fel a melegvizet, van Complex könyvtár. Elolvastam néhány mintaprogramot, kipróbáltam, pl egy hihetetlenül komoly:

#include >iostream<
#include >complex<
using namespace std;

int main()
{
complex>double< cmpx1(1, 0);
complex>double< cmpx2(1, 1);

cout << cmpx1 << " " << cmpx2 << endl;

complex>double< cmpx3 = cmpx1 + cmpx2;
cout << cmpx3 << endl;

return 0;
}

kiválóan működik. Kimenet:(1,0) (1,1) (2,1)
A programomat átírtam ezt a lib-et használva(sőt még gyorsabb is egy kicsit mint ahogy én írtam e nélkül), de a qt-creator valahogy nem szereti egy kis részlet:

...
#include >complex<
...
{
...
complex>double< cmpx2(1, 1);
...
}

fordítási eredmény:
/home/ek/work/qt/q/ocv1.cpp:22: error: expected unqualified-id before ‘<’ token
Találkoztatok már ilyen hibaüzenettel? Vagy valamit én nem állítk be jól?

Szerk: Az include után szándékosan fordítva állnak a "relációjelek", mert code code között is eltűnik a tartalma

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

"using namespace std;" van a második kódban is?

nincs, de nem is kell, mert nem std-re küldöm az adatot. De ha belerakom, akkor is ugyanez az eredmény.
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Remélem én értettem félre, de most azt írtad, hogy azért nem kell a using namespace std; mert nem az stdout-ra írsz?!

Igen, hülyeséget írtam igaz bocsi. Arra gondoltam, hogy nem az std-outra írok, így azt nem kell beállítani globálisan namespace std;-re.
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

De a complex az std nevterben van, nem?
std::complex

De szerintem itt a g++ verziokat kellene osszevetni.

Arra próbáltam célozni, hogy a using nem azzal függ össze, hogy hova írsz, hanem hogy használod-e a C++ standard könyvtár szolgáltatásait. A complex, éppúgy mint az összes többi standard könyvtárbeli entitás, az std névtérben található, tehát vagy minden használatkor std::complex-et kell írnod, vagy a fájl elejére be kell írnod a using-ot.

ps1.: fejállományokban ellenjavallt a using használata.

ps2.: egyes fordítók, ha nem követeljük meg a szigorú szabvány-kompatibilis fordítást, elfogadnak std névtér-minősítő nélküli kódot is, hogy a szabvány előtt készült kód is fordítható legyen.

Ahha értem. Én edig úgy tudtam (mivel segítség nélkül tanultam C-t, és kevés C++-t, így kiderülhet hogy egy újabb marhaságot tanultam meg), hogy ez a névtér, a be és kimenetre vonatkozik csak. Tehát valamit félreértettem. Pl hogy hova írok honnan olvasok, fizikálisan és ezeknek a beállítására szolgál, hogy most pl file, vagy standard kimenet..... amit használok. Ezek szerint mindennek van névtere a függvényeknek is (végtére az írás olvasás is az, így logikusan hangzik). Akkor honnan tudom meg hogy ez a complex, milyen névtérben van, mert ha csak az include-állományt állítom be akkor simán fordul a kód, de mikor definiálni akarom a komplex változót akkor már nem. Akár használom a standard névteret akár nem. Valamint az eddig megirt kódomban csupán annyi a teendő, hogy header állományoktól eltekintve bebiggyesztem az using namespace std-t, hogy szabványos legyen, mert miden megy szépen, csak nem írtam ezt be a filek elejére.
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Kezdjük ott, hogy mi is az a névtér (namespace): http://en.wikipedia.org/wiki/Namespace
Névtér C++-ban van, C-ben nincs.

Ha azt írod, hogy:

// test.h

void foo();
void bar(int a);

Ezzel azt mondod, hogy a foo, és a bar a globális névtérben van.

Mi a baj ezzel? Tegyük fel, hogy van egy gui lib-ed amiben van egy foo függvény, illetve van egy hálózati lib-ed amiben szintén van. Ekkor megszívtad, mert van két fv-ed aminek ugyanaz a neve.

Mi a megoldás? Elérni, hogy ne legyen ugyanaz a név.
Erre találták ki, hogy mindennek legyen egy prefixe, pl.:
OpenCV: "cv", Qt: "q" vagy "Q". Tehát ezért hívják az openCV-s szorzást cvMul-nak, a Qt-s random-ot pedig qRand-nak.

Legalábbis ez volt a régi, C-s, old school megoldás.

C++-ban bevezették a névtereket:

// lib1.h

namespace Lib1
{
    void foo();
    void bar(int a);
}

// lib2.h
namespace Lib1
{
    void foo();
    void bar(int a);
}

Ekkor minden további nélkül használhatod a Lib1::foo-t és a Lib2::foo-t.
Pl. ha használnád az OpenCV legújabb verziójában a C++-s felületet, akkor használhatnád a cv::Mat osztályt.

Azt kell még tudni, hogy az összes osztály a standard lib-ben az std névtérben van. Pl.: std::cout, std::vector, std::complex, stb.

Mivel elég macerás állandóan kiírni a névteret, ezért ha nincs névütközés, akkor egy "using namespace std;"-vel megmondhatod, hogy a megadott névtérbeli neveket névtér hivatkozás nélkül akarod használni.
Ha ütközés van, akkor a fordító szól, és az adott nevet ki kell egészítened a névtérrel.

Header fájlba nem írunk "using namespace"-t, mert az mindenhol élne, ahová include-olod, és akkor ugyanott tartanál, mint névtér nélkül.

Ha include-olod a complexet, akkor a kód persze lefordul, miért is ne tenné.
Amikor használod, eredetileg megadtad az "using namespace std;"-t, tehát a fordító először complex-et keres, majd mivel nem talál, std::complex-et is keres, azt talál, mást viszont nem, tehát használja.

A qt-s kódodban viszont nincs "using namespace", a fordító viszont nem talál complex osztályt, mert az nincs.

3 dolgot tehetsz:
- Mindenhova std::complex-et raksz. Ez kényelmetlen.
- using namespace std; Ez sok mindent berak a globális névtérbe, névütközéshez vezethet.
- using std::complex; Ez csak a complex-et emeli a globális névtérbe.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Ahha, halmazelmélet :). Köszönöm. Valóban a C-programozókból lesz a legrosszabb C++-is :D. Ami ugye nem általános, de nálam bejött. De akármelyiket választom, akkor is ugyanezt kapom. Ugyanezzel a hibával.
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Ha még mindig nem jó, Akkor rakd fel valahova a teljes .cpp fájlt, mert valószínűleg a kérdéses sor előtt van a hiba...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Sikerult a Lib2 helyett Lib1-et irni, szoval csunya-csunya nevutkozes lesz ebbol a kodbol... :-)
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Upsz... :)

Jaaa, direkt volt, hogy lássam figyeltek-e...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Nekem ez a kód rendesen működik qt-creator alatt:

#include >iostream<
#include >complex<

using namespace std;

int main(void)
{
complex>double< cmpx2(1, 1);
cout << "cmpx2 : " << cmpx2 << endl;
return 0;
}

a kimenet :
cmpx2 : (1,1)

a pro fájl tartalma :
#-------------------------------------------------
#
# Project created by QtCreator 2009-09-25T00:07:43
#
#-------------------------------------------------

QT -= gui

TARGET = qtHello
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

Amúgy mi a módja annak, hogy a < c o d e > tag rendesen működjön ? itt a hupon.

code tagen belüli < és > helyett a html kódolásukat célszerű: & gt; és & lt; (szóköz nélkül)

--
A gyors gondolat többet ér, mint a gyors mozdulat.

De ha ide nem akarod bemásolni a kódot, akkor ide is beküldheted, és akkor minden látszik:

http://hup.pastebin.com/

-

Nekem továbbra sem jó az én programom .pro fileja ez:
TARGET = q
TEMPLATE = app
LIBS += -lcv -lcvaux -lcxcore -lhighgui
SOURCES += main.cpp \
mainwindow.cpp \
ocv1.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui

------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.

Ez a -lcv ez micsoda? Biztos kell ez a standard konyvtaron alapulo, Qt-s cucchoz?
--

()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

igen kell. opencv, a kép(mátrix)kezeléshez.
------
3 fajta matematikus létezik. Aki tud számolni, és aki nem.