- Motorola Edge 50 Neo - az egyensúly gyengesége
- Samsung Galaxy Watch6 Classic - tekerd!
- Milyen okostelefont vegyek?
- Honor 400 Pro - gép a képben
- Nem várt platformon a OnePlus Nord 5
- Nothing Phone (3a) és (3a) Pro - az ügyes meg sasszemű
- One mobilszolgáltatások
- Milyen GPS-t vegyek?
- Samsung Galaxy S23 és S23+ - ami belül van, az számít igazán
- Honor 200 Pro - mobilportré
Új hozzászólás Aktív témák
-
LordX
veterán
válasz
EQMontoya #2897 üzenetére
Ez talán a link order hülyeség lesz. Nem ignorálja a paraméteredet, hanem hülyén működik a linker: a paraméterek sorrendjében megy végig a linkelendő objektumokon (.cpp esetében forditás után), és belinkeli a {main függvényt, namespace static objektumokat, eddigiek által referált függvényeket}. Szóval a .cpp-ben hiába referálsz a protobuf függvényére, linker nem találja meg, mert nem találkozik vele a cpp után.
Én is falra tudok mászni ettől..
-
EQMontoya
veterán
-
EQMontoya
veterán
bool getRandomBool()
{
return rand() % 2 == 1
}
for (int i=0;i<100;++i)
cout << getRandomBool() ? ' ' : 'X';Mit ír ki?
-
ToMmY_hun
senior tag
Igen, ügyes voltam és különbözővel próbálkoztam.
Ma is tanultam valamit. 2015-höz való Qt sajna nincs, elvileg jövő héten jön az 5.6 RC, utána valamikor (talán) lesz fordított is. Nekem sürgős, szóval fordítanom kell egyet a 2015-tel és akkor örülünk. MinGW-vel nem szórakozok, windowson elég béna szegény.
-
LordX
veterán
-
ToMmY_hun
senior tag
válasz
ToMmY_hun #2890 üzenetére
Biztosan a compiler különbözőség miatt jelentkezik a probléma. A Qt fórumon találtam egy topicot, ahol ugyanúgy definíció hiányra panaszkodott a mingw és a megoldás az azonos compiler használata volt. Sajna a Qt 5.5 (jelenlegi verzió) nem támogatja a VS 2015 C++ compilert, szóval a lehetőségek eléggé korlátozottak. Jó hír, hogy decemberben jön az új Qt (5.6) ami már elvileg kompatibilis lesz vele.
[bocsánat a duplázásért]
-
LordX
veterán
válasz
ToMmY_hun #2887 üzenetére
Mégis csak linker hiba lesz (milyen linker mondja meg sorra pontosan, hogy mi hiányzik?) - úgy tűnik nincs bent a lib-ben a függvény. Nézd meg így a lib-et, hogy benne van (most nincs megfelelő tool a gépemen), és ha nincs, akkor annak a buildelésénél kell körülnézned.
-
ToMmY_hun
senior tag
Valószínűleg ez lesz a gond. Utána jártam és a compilerek ugye kiegyszerűsítik a függvényneveket de nincs arra vonatkozó szabvány, hogy milyen módszerrel teszik ezt. Ennek következtében ha nem ugyanazzal a compilerrel történik a lib és az azt felhasználó kód fordítása, akkor nem fogja megtalálni a definíciókat. Ez magyarázatot ad arra is, hogy miért megy VS-ban.
-
ToMmY_hun
senior tag
Az error direktíva működött, szóval a headert látja. Maga a header így néz ki:
#pragma once
#include "Logger.h"
#include <iostream>
#include "ArmCreator.h"
#include "Calculation.h"
#include <chrono>
#include <thread>
#include "Communication.h"
#include "Simulation.h"
namespace RoboticArm {
class ArmRunner
{
private:
// Singleton behavior member variables
static bool instanceFlag;
static ArmRunner* single;
ArmRunner();
~ArmRunner();
// Normal member variables
Calculation* calc = Calculation::getInstance();
Matrix effectorPosition;
ArmCreator* AC = ArmCreator::getInstance();
public:
// Singleton behaviour
static ArmRunner* getInstance();
Logger* log = Logger::getInstance();
// Normal methods
void initialize();
void operate();
};
}Ez pedig a használat Qt-ben:
#include "mainwindow.h"
#include <QApplication>
#include "include/ArmRunner.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
// Ezt a harom sort adtam a projekthez:
RoboticArm::ArmRunner* arm = RoboticArm::ArmRunner::getInstance();
arm->initialize();
arm->operate();
return a.exec();
}Feltoltam dropboxra a projektet, hátha valakinek lenne ingerenciája megnézni.
-
LordX
veterán
válasz
ToMmY_hun #2884 üzenetére
Ha a fordító adja a hibaüzenetet, akkor mindegy hogy mi a lib, hol van, mivel fordítottad, mert el se jut odáig, hogy az probléma legyen. Vagy nem jó az include, vagy a deklaráció a headerben, vagy a használat. Namespace-eket, paraméter típusokat ellenőrizd, hogy nincs-e valami elgépelve, esetleg ellenőrizd, hogy tényleg jó headert próbálsz behúzni. (Utóbbihoz tipp: a deklaráció mellé tegyél egy #error BLAH direktívát, ha megkapod hibaként, akkor jó. Ha nem, akkor valami más van include-olva.)
-
ToMmY_hun
senior tag
Header include meg volt, a függvény pedig a static lib-ben van definiálva. Headerben függvény deklarációk vannak, ahogy az a nagykönyvben meg van írva. Azt is értem hogy nem találja a függvény definíciót, de pont azt kellene a lib-ből kiolvasnia, nemde?
UI: Visual Studioban hibátlanul megy a lib, használom is egy ideje.
-
LordX
veterán
válasz
ToMmY_hun #2882 üzenetére
A fordítási hibának semmi köze nincs a libekhez; azok max a linkernél tudnak hibát okozni.
Normális angolul van a hibaüzenet, nem kell tőle félni
: nincs definiálva a RoboticArm::ArmRunner::getInstance() függvény. Gondolom ez a librarynek egy függvénye, tehát kellene legyen hozzá egy header (RoboticArm.h?), ami tartalmazza a library publikus felületét ( függvények, osztályok, típusok), és be kell #include-olnod.
-
ToMmY_hun
senior tag
Sziasztok ismét!
Lenne még egy kérdésem. Csináltam egy statikus lib-et VS-ben a kódomból és szeretném azt felhasználni egy Qt projektben. A cél az lenne, hogy egy GUI-t húzzak rá, bár gondolom ezt kitaláltátok. A probléma viszont az, hogy hiába állítom be a Qt creator-ban a szükséges dolgokat, nem találja a lib-ben lévő függvény definíciókat. Lenne valakinek tippje arra vonatkozóan, hogy mi okozhatja ezt?
Az alábbi beállítások meg voltak Qt .pro fájlban:
CONFIG += c++11
LIBS += -L$$PWD/lib/ -lRoboticArmLib
PRE_TARGETDEPS += $$PWD/lib/RoboticArmLib.libTermészetesen a .lib-et is bemásoltam a helyére, azt meg is találja linker, mert ha átírom másra a nevet akkor sír miatta. A compiler viszont nem hajlandó fordítani, elszáll ezzel:
mainwindow.cpp:11: error: undefined reference to `RoboticArm::ArmRunner::getInstance()
valakinek esetleg tippje/ötlete?
-
Szirikee
újonc
Sziasztok.
Lenne egy fájlkezeléses problémám... Egy .dat kiterjesztésű fájlból olvasunk be adatokat. Pár diáknév van minden egyes sorban, és mellettük szóközzel tagolva a kapott érdemjegyük. A programban (amit bemásoltam) már megvannak az egységes számítások (az egész osztályra nézve), viszont az lenne a következő feladatunk, hogy minden egyes diákot nézzünk végig. Hogyan lehetne megcsinálni, hogy:
- irassuk ki az átlagukat (fejenként, egységesen már megvan)
- vizsgáljuk meg azt, hogy mekkora a legjobb átlag, és hogy kié?Itt az eddig megírt algoritmus (lejjebb személtetem a .dat kiterjesztésű fájlt is!):
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main() {
int n,db_nev;
float db_jegy,jegy_ossz;
string s,nev;
cout << "A jegyek.dat-bol olvasunk be." << endl;
ifstream f;
f.open("jegyek1.dat");
if (f.fail())
{
cout << "Hiba megnyitas soran" << endl;
cin.get();
return 1;
}
db_nev=0;
db_jegy=0;
jegy_ossz=0;
while(!f.eof())
{
f>>s;
n=atoi(s.c_str());
if (n==0)
{
db_nev++;
cout<<endl<<s<<" ";
}
else
{
db_jegy++;
jegy_ossz=jegy_ossz+n;
cout<<s<<" ";
}
}
f.close();
cout<<endl<<endl<<"Nevek szama: "<<db_nev<<endl;
cout<<"Jegyek szama: "<<db_jegy<<endl;
cout<<"Jegyek osszege: "<<jegy_ossz<<endl;
cout<<"Az osztaly atlaga: "<<jegy_ossz/db_jegy<<"\n"<<endl;
cin.get();
return 0;
}
.DAT KITERJESZTÉSŰ FÁJL:
Andi 4 4 3 5
Bela 4 5 4 3
Geza 2 2 4 4
Aladar 3 1 4 5
Eva 5 5 5
Eszter 3 3 5 4
Sandor 4 5 3 2
Előre is köszönöm a válaszokat! -
ToMmY_hun
senior tag
válasz
jattila48 #2877 üzenetére
Lehet, hogy túlbonyolítom. Leírom mi a végső cél. Adott egy program, amely számításokat végez és socket-en küldi le ezeknek az eredményét 5 kliensnek. A klienseknek folyamatosan csatlakozva kell lenniük, különben az adatok érvénytelenek. A főprogram alatt gondolom a fő végrehajtási szálat érted. A további szálakat úgy oldottam meg, hogy csináltam egy SocketComm osztályt, abban van egy statikus metódus, ami a kommunikációért felel. Ez a statikus metódus az osztályban lévő attribútumokból olvas és küld, magát a kapcsolatot nem ő építi fel hanem az osztály konstruktora. A thread indításáért felelős függvénynek a statikus függvény pointerét adom át (ezt nevezhetjük callbacknek), amit így futtat a threadben és ezzel azt is megoldottam, hogy a későbbiekben ha változik a kliensek száma, akkor az indítások számát kell csak változtatni.
UI: Egyelőre azért van egy thread, mert csak server -> kliens irányú a kommunikáció, a válaszokat később szeretném beépíteni és ahhoz valóban kelleni fog a kliensenkénti thread.
-
LordX
veterán
válasz
jattila48 #2875 üzenetére
Mivel a Copy elision-t már 12 éve engedi a szabvány, ma már nem nagyon van olyan fordító, ami nem tudná. A 2000-es évek elején még volt.
A szabvány logikáját kell követni: ha valamit copy/direct initialization-el definiálsz, akkor konstruktor overload van. Ez akkor is működik, ha valami kitekert konstruktorod van (const rvalue ref-et váró, leszármazott referenciát váró, stb.). Ha ez megvan, utána jön a "triviális" optimizáció, de ez csak akkor van, ha copy vagy move konstruktor játszik, a fura konstruktorok nincsenek kioptimalizálva - és erősen valószínű, hogy azokat azért csináltad, mert szükséged van rá.
Csak ugye a triviális annyira nem is triviális - mi van, ha van egy olyan kódod, hogy:
T f() { return T(); }
T g() { return f(); }
void h() { T x = g(); }(Tetszőlegesen bonyolult f és g függvényekkel, nem csak ilyen kis Móricka példával.) Hány darab copy/move van itt, amit mellőzni lehet? 1? 2? 4? Erősen attól függ, hogy mit inline-olsz, ami már alapból egy optimizációs kérdés, és másik fordító máshogy dönthet..
-
jattila48
aktív tag
válasz
ToMmY_hun #2867 üzenetére
Nem igazán értem mit szeretnél, de tartok tőle, hogy túlbonyolítod. Ha TCP listen socket-ről van szó, akkor a főprogramban listen-el, majd az accept-ált connected socket-tel új thread-et indítasz. Minden kapcsolathoz külön thread-et, tehát nem 1 vagy 2 thread-ed lesz, hanem annyi, amennyi kapcsolatot fogadsz (természetesen ezek dolguk végeztével (pl. a kliens lezárja a kapcsolatot) "elhalnak"). Az új thread-nek paraméterként csak a konnektált socket-re lesz szüksége, amit void *-ra castolva a CreateThread-nek átadsz.
Te valamiféle callback függvényt akarsz így member function pointerrel csinálni? Ez egyfajta delegate lenne? Miért csak 1 thread-et akarsz indítani? -
jattila48
aktív tag
Ez alapján valóban így lehet, ahogy írod. Én a Visual Studio 2012-őt használom, és még debug módban sem hívja a copy ctort T s=T() -re. Ellenben a my_matrix-ot érték szerint visszaadó operátoroknál debug módban nincs RVO (meghívódik a copy ctor), release módban pedig van RVO, annak ellenére, hogy a copy ctor-ban logolás van. Mondjuk azt nem értem, hogy a T x=t (ahol t temporális (és T típusú, bár talán ez sem fontos)) inicializálásnál mégis miért hívnák meg a copy ctort? Egyáltalán van ilyen fordító? A T s{} inicializálást a VS2012 nem ismeri, ezért nem azt használtam.
-
LordX
veterán
válasz
EQMontoya #2870 üzenetére
Nem, mellékhatással rendelkező konstruktor is áldozatul eshet a copy elisionnek:
[class.copy] bekezdés (jó hosszú alfejezet, a vége felé):
"When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects."
(A "certain criteria" az (N)RVO, a "hagyományos" copy elision és a throw ill catch esetében az exception objektumok konstrukciója listát tartalmazza.)
-
LordX
veterán
válasz
jattila48 #2871 üzenetére
De van, a szabvány ezt mondja, [dcl.init] szekció:
"The initialization that occurs in the form
T x = a;
as well as in argument passing, function return, throwing an exception, handling an exception, and aggregate member initialization is called copy-initialization. [ Note: Copy-initialization may invoke a move. — end note ]
(...)
If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated, and the best one is chosen through overload resolution (13.3). The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s)."Magyarul, ha a változó és az inicializáló típusa ugyanaz (modulo CV), akkor:
1. Kiértékeli az egyenlő jel jobb oldalát.
2. Overload resolution kitalálja melyik konstruktor kell (azonos típus miatt copy vagy move), és azt hívja meg a jobb oldallal, mint paraméterrel.
Tehát, T x = T();
1. T() default-konstruál egy temporális T-t
2. Overload resolution megtalálja a move konstruktort (vagy ha nincs, copy), és meghivja
3. Expression temporálisa destruálásMivel a bekezdés a direkt inicializálás és a copy inicializálás (ahol az inicializáló kifejezés ugyanolyan típusú) között nem tesz különbséget a T x = valami; és T x{valami}; között, a valami helyére behelyettesítve a T()-t, azt kapod, hogy T x{T()};.
Demo Az -fno-elide-constructors kapcsoló kapcsolja ki a copy elisiont.
-
jattila48
aktív tag
válasz
EQMontoya #2870 üzenetére
A T s=T(); deklarációban nincs copy elision (és másfajta optimalizáció sem), mert nincs rá szükség, ha triviális a copy ctor, ha nem. Egyszerűen a T() ctor hívódik meg és hozza létre az s-et mindenféle optimalizációtól függetlenül.
"Ha mondjuk van ott egy logolás, akkor simán le fog futni a default ctr majd a copy"
Mármint a copy ctor-ban van logolás? Nem fog lefutni, és a log sem fog kiíródni, és ez nem az optimalizáció miatt van, hanem mert deklarációban ez egyszerűen így működik. Próbáld ki! Mellesleg copy elision esetén (itt nem aróól van szó!) akkor is kioptimalizálhatja a copy ctor hívást, ha van megfigyelhető mellékhatása (ol. logolás). Ez is benne van a szabványban. -
EQMontoya
veterán
válasz
jattila48 #2869 üzenetére
The C++ language standard generally allows implementations to perform any optimization, provided the resulting program's observable behavior is the same as if, i.e. pretending, the program was executed exactly as mandated by the standard.
Szóval ott csak addig lesz copy elision, ameddig a copy ctr. triviális, Ha mondjuk van ott egy logolás, akkor simán le fog futni a default ctr majd a copy, mert nem optimalizálhatja ki.
-
jattila48
aktív tag
válasz
jattila48 #2868 üzenetére
Bocs, értékadó operator helyett természetesen copy ctor-t akartam írni. Szerintem erre gondoltál, hogy T()-vel létrejön egy temporális objektum, amit a copy ctor paraméterként átvéve létrehozza az s-et. De ez nem igaz. Csak a default ctor hívódik meg a deklarációban, és ez független az RVO-tól (copy elision).
-
jattila48
aktív tag
T s=T(); nem hívja az értékadó operátort, ez mindössze egy default ctor hívás. Ennek nincs köze a copy elision-höz és egyéb optimalizációhoz sem, debug módban is csak ennyi. Amit írtál az le sem fordul, lokális fv.-ként próbálja értelmezni. Egyébként a T s; pedig az alaptípusok miatt nem elegendő (pl. int), mert deklarálja az s-t, csak éppen nem inicializálja 0-val. Szóval szerintem jó ez így. Egyéb "hiba"?
-
ToMmY_hun
senior tag
válasz
EQMontoya #2866 üzenetére
Először is köszi a választ! Azért szeretném ezt használni, mert lenne egy osztályom amiben egy szerver socketet szeretnék futtatni és a socketet új threadben akarom indítani. Az új threadet az osztály konstruktorában indítom és ugye ott kéne neki átadni a futtatandó metódust is, ezért lenne szükségem a pointerre. Az osztálynak csak a socket által kiküldött vektor feltöltése és magának a socket kommunikációnak a lebonyolítása a feladata, egy példány lesz belőle. Ha erre lenne valami szebb megoldási javaslat, akkor annak örülnék és köszönöm előre is! Addig is kipróbálom amit javasoltál.
Static metódus ugye azért nem frankó, mert akkor nem érem el az osztály belső változóit. Persze ha úgyis csak egy példány lesz, akkor lehet singleton és úgy el is érem, de nem tűnik szimpatikusnak a megoldás, tuti van ennél szebb.
-
EQMontoya
veterán
válasz
ToMmY_hun #2865 üzenetére
class A {
public:
int f();
int (A::*x)(); // <- declare by saying what class it is a pointer to
};
int A::f() {
return 1;
}
int main() {
A a;
a.x = &A::f; // use the :: syntax
printf("%d\n",(a.*a.x)()); // use together with an object of its class
}Ugyanakkor muszáj felhívom a figyelmed, hogy ha ilyet akarsz csinálni, akkor valamit nagyon elb@sztál a tervezésnél, vagy nagyon nem ismersz valami olyan patternt, amivel kiváltható lenne ez a működés. Látatlanban nem tudom, hogy pontosan mi lehet szükséged, de a visitort, decoratort, nézd meg.
-
ToMmY_hun
senior tag
Sziasztok!
Tudnátok egy jó megoldást mondani arra, hogy miként tudnám elérni egy osztály konstruktorában az adott osztályon belüli metódus pointerét? Static-ként természetesen megy, de objektumhoz tartozó kellene.
-
Whysperer
addikt
válasz
ToMmY_hun #2862 üzenetére
Koszi az oldalt. Ezt kerestem...pont ilyesmi miatt irtam ide. Nem azert hogy Ti irjatpk meg... Ifen szamoltam egy eves munkankat fel evre redukalna es igy izon simulaciora is volna ido es kapacotas... Egy evrol fel evre csokkenes.... Eleg a fejlesztesre valo indokra. Mondom nem olyan embert keresek.. Aki ejjel nappal dolgozva megirja (bar ez sem kizart) hanem aki szakmailag tudok vele ertekezni errol.
Koszonom az utmitatast.
-
ToMmY_hun
senior tag
válasz
Whysperer #2861 üzenetére
Az rendben van hogy jól menő cégről van szó, ezt örömmel hallom. Itt viszont az a probléma hogy Te egyedül próbálod megítélni a projekt megvalósíthatóságát és Te szeretnéd a mérnökökre erőltetni úgy, hogy annyira nem vagy jártas a témában (abból hogy egy fórumban kérdezgetsz megvalósíthatóságról nekem ez jön le). Inkább közelítsd meg úgy a problémát, hogy a mérnökökkel egyeztetve próbáltok megoldást találni. Nagy eséllyel jobban értenek ehhez, mivel hasonló dolgokkal foglalkoznak nap mint nap. Azt sem árt kiszámolni, hogy az általad kért fejlesztés mennyi munkaórába kerül és mennyi munkaórát spórol, anyagilag egyáltalán megéri-e.
Elvontabb szakmai kérdésekhez pedig tudom ajánlani a StackOverflow oldalt. Nagy felhasználóbázisának köszönhetően valószínűleg kapsz választ ilyen speciális kérdésre is.
-
Whysperer
addikt
válasz
ToMmY_hun #2860 üzenetére
Assasin Creed Cinematic-ok, Desitiny és hasonló volumenü cinematico-kat gyártunk. Válaszolva a kérdésedre. Igen érdmes mert a ruha szimulációk sebességét felgyorsítaná. Sokszorosára. Ami nem mindegy. Föleg amikor 20-30 perc alatt megy le és utánna meg,ha valami nem jó akkor finom hangolni és megint elidíntani. Azután megint ha megfelelő és van 200 más és más szituáció nagyon sok beállítással. Maya Ncloth sajnos ilyen macerás.. minden ruha máshogy reagál más jelenetben más poligon számmal más környezeti hatással már animációval. Szóval nincs sablon.
Szóval igen szükséges és és érdemes.Mivel. Mert az Animációs csapat is tudna részesülni a dologból.
"fórumos igazolás" nem elegendő csak hátha iylen topicba kaptam volan ötletet.. Most várjuk a forráskódot Nvidia developmentől és a Maya supporttól. Találtam több müködő refferencia munkát. Ezekre várom a emaileket.
-
Whysperer
addikt
Sziasztok C++ -ba meglehetne oldani amit python topicba írtam. csak nem pythonnal hanem C++ val. [link]
-
jattila48
aktív tag
válasz
jattila48 #2852 üzenetére
A szorzás gyorsítása ilyen lehet:
template<typename T,int n,int m,int k> my_matrix<T,n,m> operator*(const my_matrix<T,n,k> &a,const my_matrix<T,k,m> &b){
my_matrix<T,n,m> c(dummy);
int i,j,l;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
T s=T();
for(l=0;l<k;++l){
s+=a.matrix[i][l]*b.matrix[l][j];
}
c.matrix[i][j]=s;
}
}
return c;
}Ehhez csak a my_matrix osztályba fel kell venni friend-nek:
template<typename T,int n,int m> class my_matrix{
template<typename T,int n,int m,int k> friend my_matrix<T,n,m> operator*(const my_matrix<T,n,k> &a,const my_matrix<T,k,m> &b);
public:
typedef T scalar_type;
...Végül is nem bonyolult, és mégsem kell eltárolni a méretet.
-
jattila48
aktív tag
válasz
jattila48 #2851 üzenetére
A némileg optimalizált változat:
#ifndef _MATRIX_
#define _MATRIX_
#include <assert.h>
#include <iostream>
static struct dummy_type{}dummy;
template<typename T,int n,int m> class my_matrix{
public:
typedef T scalar_type;
my_matrix(const dummy_type &){}
my_matrix(const my_matrix& mm){
std::cout << "copy ctor" << std::endl;
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=mm.matrix[i][j];
}
}
}
explicit my_matrix(T x=T()){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=x;
}
}
}
my_matrix & operator=(const my_matrix &mm){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=mm.matrix[i][j];
}
}
return *this;
}
my_matrix & operator+=(const my_matrix &mm){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]+=mm.matrix[i][j];
}
}
return *this;
}
my_matrix & operator*=(T c){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]*=c;
}
}
return *this;
}
my_matrix operator+(const my_matrix &mm) const{
//return my_matrix(*this)+=mm;
my_matrix t(dummy);
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
t.matrix[i][j]=matrix[i][j]+mm.matrix[i][j];
}
}
return t;
}
my_matrix operator*(T c) const{
my_matrix t(dummy);
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
t.matrix[i][j]=c*matrix[i][j];
}
}
return t;
}
const T & operator()(int i,int j) const{
assert(i<n && j<m && i>=0 && j>=0);
return matrix[i][j];
}
T & operator()(int i,int j){
return const_cast<T &>(static_cast<const my_matrix *>(this)->operator()(i,j));
}
private:
T matrix[n][m];
};
/*
template<typename T> T operator+(T a, T b){
return T(a)+=b;
}
*/
template<typename T,int n,int m,int k> my_matrix<T,n,m> operator*(const my_matrix<T,n,k> &a,const my_matrix<T,k,m> &b){
my_matrix<T,n,m> c(dummy);
int i,j,l;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
T s=T();
for(l=0;l<k;++l){
s+=a(i,l)*b(l,j);
}
c(i,j)=s;
}
}
return c;
}
template<typename T> T operator*(typename T::scalar_type c,T &A){
return A*c;
}
#endifEbben már nincs fölösleges copy ctor hívás. Csak a my_matrix-ot érték szerint visszaadó fv.-ek hívják a copy ctort, legalábbis debug verzióban vagy nem C++11 kompatibilis fordítóval fordítva, de az újabb fordítók az RVO miatt ezt is ki optimalizálják (copy elision. mindig!). A dummy_type típusú dummy változó csak a megfelelő ctor overload kiválasztása miatt lett bevezetve. A my_matrix(const dummy_type &) ctor semmit nem csinál, ez csak a megfelelő méretű inicializálatlan elemű üres mátrix létrehozására kell. Az előző verzióban erre a copy vagy default ctort kellett használni, azonban amikor az így létrehozott mátrix elemei (pl. összeadással) amúgy is felül lesznek írva, fölösleges az elemek inicializálása. Ez a ctor persze nem használható "rendes" objektum létrehozására, mert az így létrehozott objektum önmagában használhatatlan. Célszerű lenne ezért private-ba tenni, de akkor az ezt hívó free fv-eknek friend-nek kéne lenni (TODO). A default ctort is lehetett volna így használni, azonban akkor ezzel nem lehetne objektumot létrehozni. A mátrix szorzáson is lehetne gyorsítani pl. úgy, hogy a * operatort az összes különböző méretű, azonos skalár típusú my_matrix friend-jévé tesszük, és nem az elemkiválasztó operator()(int,int)-t hívjuk, hanem közvetlenül a matrix[j]-ket, de ekkor el kéne tárolni a my_matrix osztályban az n,m méret template argumentumokat. Valamivel gyorsabb lenne, azonban lényegesen rondább is.
-
jattila48
aktív tag
válasz
EQMontoya #2847 üzenetére
Az assert valóban nem véd alul indexelés ellen, nem akartam annyit írni. Ez amúgy is csak egy vázlat. Megoldható úgy is ahogy írod, de szerintem így elegánsabb (és talán hatékonyabb). Amúgy nem sok eset van, amikor a const_cast-nak létjogosultsága van, ez az egyik (más most nem is jut eszembe), ezt is szerettem volna bemutatni. Ha teljesen kidolgoznám a példát, akkor pl. a scalar_type-ot is megnézném, hogy triviálisan másolható-e, és ettől függően írnék vagy nem írnék hozzá copy ctort és értékadó operátort. Esetleg a default ctort lenne érdemes átalakítani, hogy az összes elemet adott értékkel feltöltse (ekkor persze már nem default) pl. így:
explicit my_matrix(T x=T()){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=x;
}
}
} -
jattila48
aktív tag
válasz
EQMontoya #2845 üzenetére
Valóban, az operator+ tagoperator helyesen my_matrix operator+(const my_matrix &mm) const
operator* tagoperator pedig nincs. const_cast azért kell, mert a nem const verzió ugyanaz mint a const verzió, csak nem const objektum egy elemére ad vissza nem const referenciát. Itt most egyszerűbb lett volna beírni ugyanúgy azt az egy sort, azonban ha const verzió változik, változtatni kell a nem const verziót is. Bonyolultabb esetekben is általában ez a megfelelő megoldás. A const_cast-ok csak a fordítónak szólnak, nem generálódik kód hozzá, így aztán hatékony is. -
jattila48
aktív tag
válasz
Boryszka #2831 üzenetére
A matrix_base-től való öröklés szerintem felesleges, főleg private módon. A következő header jó kiindulás lehet:
template<typename T,int n,int m> class my_matrix{
public:
typedef T scalar_type;
/*
my_matrix(const my_matrix& mm){
int i,j;
for(int i=0;i<n;++i){
for(j=0j<m;++j){
matrix[i][j]=mm[i][j];
}
}
}
my_matrix &operator=(const my_matrix &mm){
}
*/
my_matrix(){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=T();
}
}
}
my_matrix & operator+=(const my_matrix &mm){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]+=mm.matrix[i][j];
}
}
return *this;
}
my_matrix & operator*=(T c){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]*=c;
}
}
return *this;
}
my_matrix operator+(const my_matrix &mm){
my_matrix t(*this);
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
t.matrix[i][j]+=mm.matrix[i][j];
}
}
return t;
}
my_matrix & operator=(const my_matrix &mm){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]-=mm.matrix[i][j];
}
}
return *this;
}
const T & operator()(int i,int j) const{
assert(i<n && j<m);
return matrix[i][j];
}
T & operator()(int i,int j){
return const_cast<T &>(const_cast<const my_matrix *>(this)->operator()(i,j));
}
private:
my_matrix(const my_matrix &a,const my_matrix &b){
int i,j;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
matrix[i][j]=a.matrix[i][j]+b.matrix[i][j];
}
}
}
T matrix[n][m];
};
/*
template<typename T> T operator+(T a, T b){
T c(a);
c+=a;
return c;
}
*/
template<typename T,int n,int m,int k> my_matrix<T,n,m> operator*(const my_matrix<T,n,k> &a,const my_matrix<T,k,m> &b){
my_matrix<T,n,m> c;
int i,j,l;
for(i=0;i<n;++i){
for(j=0;j<m;++j){
T s=T();
for(l=0;l<k;++l){
s+=a(i,l)*b(l,j);
}
c(i,j)=s;
}
}
return c;
}
template<typename T> T operator*(T A,typename T::scalar_type c){
T t(A);
t*=c;
return t;
}
template<typename T> T operator*(typename T::scalar_type c,T A){
return operator*(A,c);
}Copy ctor-t és értékadó operátort csak akkor kell írnod, ha a scalar_type (a mátrix elemeinek típusa) nem triviálisan másolható. Ezt pl. type trait-tal is ellenőrizheted. A + operator lehet tfv. is, ha nincs más típusról implicit konverzió. Különben free fv.-nek kell lenni. Én most nem írtam 1 paraméteres ctort, így nem lehet implicit konverzió (kivéve, ha más osztálynak van my_matrix-ra konverziós operátora).
-
EQMontoya
veterán
Én azért alapvetően igyekszem távol tartani magam tőle.
Persze, van, amikor kényelmesebb és tényleg van, de láttam már referenciát váró függvényt pointerrel meghívva lefordulni és lefutni az elb..ott konverziós konstruktorok miatt. Szóval amit nem használunk feltétlenül, az legyen explicit, és alap típusok esetén mindenképp. -
EQMontoya
veterán
-
LordX
veterán
válasz
EQMontoya #2838 üzenetére
struct X {};
struct Y {
Y() = default;
Y(X) {}
Y operator +(const Y& right) { return *this; }
};
Y operator *(const Y& left, const Y& right) { return left; }
void f() {
X x1, x2;
Y y1, y2;
auto t1 = x1 + y1; //member op - nem fordul le
auto t2 = y2 + x2; //member op - lefordul
auto t3 = x1 * y1; //free op - lefordul
auto t4 = y2 * x2; //free op - lefordul
} -
EQMontoya
veterán
Ha az operátor paramétere ugyanolyan típus (vagy - mint jelen esetben - hasonló típus, ami valamelyik template paraméterében eltér), akkor mindegy, mert így is - úgy is jó lesz.
Abban igazad van, hogy teljesen más típus esetén (pl. konstanssal szorzás) nyilván nem célszerű.
Én azért azt vallom, hogy amit nem feltétlen kell frienddel megcsinálni, azt ne csináljuk. -
LordX
veterán
válasz
EQMontoya #2835 üzenetére
Erősen ellenjavallott kétoperandusú operátoroknál a tagfüggvényes megvalósítás, ha létezik implicit konverzió más típusokról. Eléggé hülyén néznek a userek, ha a*b lefordul, b*a nem. (Jó, most a mátrixszorzásnál ez nem annyira számít, mert amúgy is csak a megfelelő mérteket kell hagyni.) Ha lehetséges, legyen az operátor szabad függvény, és legyen friend, ha belső dolgokban is turkál.
-
Boryszka
tag
Üdv!
Szeretnék kis segítséget kérni, mivel template segítségével szeretnék elkészíteni egy feladatot, amely kétdimenziós, dimenziónként tetszőleges méretű (NxM-es) mátrixot reprezentál. Az osztály sablonparaméterei határozzák meg a mátrix alaptípusát (T) és méreteit (N és M). A matematikai szabályoknak megfelelően paraméterezett sablonpéldányok objektumai között meg kell valósítani az összeadás és kivonás műveleteket (NxM-es mátrixok között), a szorzás műveletet (NxK és KxM-es mátrixok között), valamint a konstanssal (azaz a mátrix alaptípusával) való szorzást. A műveleteket a megfelelő (+, -, *) C++ operátorok felüldefiniálásával kell megvalósítani.
Valami ilyesminek kell kinéznie:
template<class T, int N, int M>
class my_matrix : matrix_base {
public:
/** A sablonpéldány rendelkezik default konstruktorral. */
my_matrix();
/**
* A mátrix elemeihez való hozzáférést a kétparaméteres függvényhívás
* operátor felüldefiniálása biztosítja.
*/
const T& operator()(int n, int m) const;
T& operator()(int n, int m);
}; -
CoolMan
MODERÁTOR
Legyetek szívesek befejezni az értelmetlen veszekedést, offolást! Nem szeretnék ezért visszajönni. Köszönöm.
-
sztanozs
veterán
válasz
#99472384 #2820 üzenetére
Nem tudom mekkora lemezeid lehetnek - de gy 32 GB-os pendrive kb 5.000 forint, amire bőven tudnál szükség esetén menteni (de a feléért is kapsz feleakkorát). Ha tele van a lemez és fejleszteni szeretnél, akkor szvsz törölj egy-két filmet / zenét (ami lejön max 1-2 óra alatt), ne a .NET keretrendszert (amit amúgy nem is tudom, hogy tudál rendesen eltávolítani).
Amúgy azt pl nem értem, miért kell egyáltalán a DVD írót frissíteni - nem írta 20x-osan a DVD-t?
Ha meg nem sértelek, mekkora lemezekről és pendrájvokról beszélünk?
-
LordX
veterán
válasz
#99472384 #2820 üzenetére
Az Expressben nincs MFC, próbálkozz inkább a Professional-al (Community Edition név alatt ingyenes, nem-kereskedelmi célra).
Az, hogy fél perc, honnan a tökömből vetted? Nincs hozzá projektfájl, úgyhogy minden beállitást meg kell csinálni, ami már alapból nem fél perc.
-
#99472384
törölt tag
válasz
sztanozs #2819 üzenetére
Sajnos ez jelenleg nem járható út, ezen a kísérleten már a legelső pillanatban túl voltam.
( Visual Studio Express 2015 )Sajnos mindkét merevlemezem, mindkét pendrive-om csutkára tele van, pontosabban az éppen használatban lévő HDD-n még valami kevéske helyem van, de a Visual Studio + a NET keretrendszer együtt már nem fér rá, pont más miatt kellett nemrég legyalulnom a NET keretrendszert, mert most épp semmihez sem kell.
Sajnos a PHILIPS multi DVD íróm egy hibás gyári firmware miatt (frissítve lett, de bugos volt gyárilag), szépen egy DVD film közben kilehelte a lelkét, a következő LG multi DVD íróm pedig jelenleg javítás alatt van, (csak nincs sok időm foglalkozni vele, így picit csúszik a project) úgyhogy még DVD-t sem tudok írni per pillanat, hogy szabad helyem legyen.
De szerinted ha nem így állnék, akkor mást kérnék meg egy fél perces+kávészünet idejű fordításra???
-
#99472384
törölt tag
válasz
EQMontoya #2814 üzenetére
Üdv.
Tévedsz, nem maradt ki az utánaolvasás, de nem is ezzel van a gond, mert nagyvonalakban értem.
A fordítással van a gond, mivel nincs Visual C++ -om, ami meg ingyenes, az nem fordítja le, de nem is csoda mert szinte önmagával sem kompatibilis.Hogy milyen operációs rendszerre kell, azt leírtam. 32 vagy 64 bit szinte tökmindegy, mert 64bites Athlonom van, és az op rendszerből is van 32 és 64 bites verzióm. Persze a 32bites verzió lenne a jobb megoldás. Az meg hogy mit és hogyan számol, az tökmindegy, és nincs egyszerűbb megoldás, ugyanis amit számolnia kell az eleve nem publikus.
Ezt a programot is azért írta egy német fickó, mert az egyik ilyen fájlja megsérült, és használhatatlanná vált.No, de ezek jelenleg lényegtelen információk.
Amit linkeltél, az eddig is világos volt számomra, de mint írtam nem is ez a gond.
-
jattila48
aktív tag
válasz
yossarian14 #2796 üzenetére
A cout << ++j << ": " << fileName << endl; sorban a j honnan jön? Egyébként, ha ez a ciklus lassú, akkor pont ez konzolra kiíró sor lassítja. Oprendszertől (és a runtime librarytól) függően ez meglehetősen lassú tud lenni.
-
#99472384
törölt tag
Sziasztok, Üdv. Mindenkinek!
Segítséget szeretnék kérni Visual C++ fordításban. Van egy kis forráskódom, amit sajnos nem tudok futtatható programmá fordítani.
Eddig Pascal és Delphi programozással kísérleteztem, ezekkel nincs is gondom, de sajnos az említett forráskód Visual C++-ban íródott, és ilyen fejlesztőrendszerem nincs, ami meg ingyenes volt, azzal sehogyan sem jutottam előrébb, mert valami nem igazán működött a fordításnál. Egy jópár hibaüzenettel leállt a fordítás. (pl. stdafx.h hiányzik a fordítónak) Ráadásul a C++-ban nem is igazán vagyok járatos.Szóval abban kérném a hozzáértők segítségét, hogy legyenek szívesek megnézni a kódot, hogy egyáltalán jó-e, és ha igen, akkor legyen szíves valaki ezt nekem le is fordítani egy futtatható programmá. Természetesen Windows-ra kell, és ugye ez konzol progi. Sajnos a program íróját már nem lehet elérni, de állítólag működik, csak én sehogy sem boldogulok...
Az is jó lenne, ha valaki bővebben kommentezné a kódot, mert akkor megpróbálom Delphi-ben megírni, hátha sikerül.Íme a forráskód:
#include "stdafx.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
#include "test.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// The one and only application object
CWinApp theApp;
using namespace std;
unsigned long CalcChecksum( unsigned char* buffer, unsigned long len, unsigned long seed );
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
int fh;
unsigned char buffer[0x8000];
unsigned short len = 0x7FFC;
unsigned short count;
unsigned short seed = 1;
unsigned long chkSum;
// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
if( argc != 2 )
{
cout << "usage: CalcChecksum.exe drive:\\path\\info.dvr" << endl;
return 0;
}
fh = _open(argv[1], _O_RDONLY | _O_BINARY);
if( fh == -1 )
{
cout << "Error opening file " << argv[1] << endl;
}
count = _read( fh, buffer, 0x8000 );
if( count != 0x8000 )
{
cout << "Error reading file " << argv[1] << endl;
return 0;
}
_close(fh);
chkSum = CalcChecksum( &buffer[0], len, seed );
_ultoa( chkSum, (char*)&buffer[0], 16 );
cout << "Checksum: 0x" << buffer << endl;
}
return nRetCode;
}
unsigned long CalcChecksum( unsigned char* buffer, unsigned long len, unsigned long seed )
{
unsigned char nrOfSegments;
unsigned long regECX = seed;
unsigned long regEDX = 0;
unsigned long regEDI = 0;
unsigned long retVal;
nrOfSegments = len / 0x15b0;
for( unsigned short i = 0; i < nrOfSegments; i++ )
{
for( unsigned short j = 0; j < 0x15b0; j++ )
{
regEDX = buffer[i*0x15b0+j];
regECX += regEDX;
regEDI += regECX;
}
regECX = regECX % 0xFFF1;
regEDI = regEDI % 0xFFF1;
}
for( i = (nrOfSegments*0x15b0); i < len; i++ )
{
regEDX = buffer[i];
regECX += regEDX;
regEDI += regECX;
}
regECX = regECX % 0xFFF1;
regEDI = regEDI % 0xFFF1;
retVal = (regEDI << 16) | regECX;
return( retVal );
}ennyi lenne...
Ha valaki tudna segíteni, és lefordítaná nekem, akkor azt nagyon szépen megköszönném!
-
LordX
veterán
válasz
yossarian14 #2796 üzenetére
Milyen platform? Visual Studionak az iostream implementációja sajnos nagyon gyenge teljesítményű, GCC-é (akár MinGW-ben is) jobb (mondjuk annak meg vannak nem-konform hülyeségei, de halandó programozónak nem számít).
Valamint még erősen ajánlott kikapcsolni az io szinkronizálást:
std::ios_base::sync_with_stdio(false); -
EQMontoya
veterán
válasz
yossarian14 #2803 üzenetére
Hol száll el, és mivel?
-
yossarian14
tag
válasz
EQMontoya #2801 üzenetére
Így írtam be, de elszállt a program, nem fut le. Gondolom valamit rossz helyre tettem.
void process(string fileName) {
cout << ++j << ": " << fileName << endl;
ifstream file(fileName);
string line;
const int size = 10*1024*1024;
char mybuffer [size];
file.rdbuf()->pubsetbuf(mybuffer,size);
while (getline(file, line))
{
}
} -
xavix13
őstag
válasz
dabadab #2800 üzenetére
Azt hogy hogyan kellene beolvastatni a játékos számait egy tömbbe ellenőrzötten, egy ciklusban, letudnád írni? Nekem nem igazán akart összejönni, csak így ahogy sikerült, ami nyilvánvalóan rossz.
Nem tudom ezek a container template-ek micsodák, de egyelőre nekünk még ilyet nem tanítottak, még ha el is hiszem hogy jobb volna azzal csinálni.
-
EQMontoya
veterán
válasz
yossarian14 #2798 üzenetére
int size = 10*1024*1024
char mybuffer [size];
file.rdbuf()->pubsetbuf(mybuffer,size);
(nyilván a ciklus elé rakva)Ez segít valamit?
Új hozzászólás Aktív témák
Hirdetés
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- AMD K6-III, és minden ami RETRO - Oldschool tuning
- Veszprém és környéke adok-veszek-beszélgetek
- Linux kezdőknek
- Motorola Edge 50 Neo - az egyensúly gyengesége
- Macron betiltatná az EU-ban a közösségi médiát a 15 év alattiaknak
- Nintendo Switch 2
- Szeged és környéke adok-veszek-beszélgetek
- Milyen széket vegyek?
- Raspberry Pi
- gban: Ingyen kellene, de tegnapra
- További aktív témák...
- HP Elitebook 840 G3 laptop (14FHD/I5-G6/8GB/256SSD/Matricázott) - Akku X
- Asus Rog Strix Gamer laptop makulátlan állapotban
- ThinkPad T14 Gen4 14" FHD+ IPS érintő Ryzen 5 PRO 7540U 16GB 256GB NVMe ujjlolv IR kam gar
- 16GB-os SODIMM (notebook) DDR4 RAM bazár - nézz be, lesz, ami kell neked!
- HP 15-af105nh laptop (15,6FHD/AmdQuad/4GB/128SSD/Magyar) - Akku X
- iKing.Hu - Xiaomi 14 Ultra - Ultra White - Használt, karcmentes
- Bomba ár! HP 250 G8 - i5-11GEN I 16GB I 512GB SSD I HDMI I 15,6" FHD I HDMI I W11 I Cam I Garancia!
- Lenovo ThinkPad X13 G2 multitouch
- BESZÁMÍTÁS! Gigabyte H610M i5 13400F 32GB DDR4 512GB SSD RTX 3070 8GB Zalman Z1 Plus Enermax 750W
- Bomba ár! Dell Latitude 7280 - i5-7GEN I 8GB I 256SSD I 12,5" FHD I Cam I W11 I Garancia!
Állásajánlatok
Cég: CAMERA-PRO Hungary Kft
Város: Budapest
Cég: PC Trade Systems Kft.
Város: Szeged