Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++] Przekazanie danych ze strumienia bezpośrednio do funkcji

Ostatnio zmodyfikowano 2018-06-02 02:01
Autor Wiadomość
Doriak
Temat założony przez niniejszego użytkownika
[C++] Przekazanie danych ze strumienia bezpośrednio do funkcji
» 2018-06-01 22:10:53
Cześć wszystkim,

Piszą pewien program natknąłem się na pewien problem. Jako że jest to program zaliczeniowy na studia, to szukam jak najbardziej książkowego, eleganckiego rozwiązania.

Cała sprawa wygląda następująco:
Mam dwa obiekty utworzone z klas zewnętrznej biblioteki (ich edycja nie wchodzi w grę). Pierwsza posiada przeciążony operator strumieniowy >> na zmienną typu string, a druga klasa posiada metodę przyjmującą za argument zmienną tego samego typu poprzez wskaźnik &. Według dokumentacji kod wygląda tak (w faktyczne deklaracje i definicje w bibliotece się nie wczytywałem...):

C/C++
class Klasa1
{
public:
    Klasa1 operator >>( std::string & 1zmienna )
};

class Klasa2
{
public:
    void funkcja( const std::string & 2zmienna )
}

Zadaniem funkcji jest modyfikacja obiektu, dla którego jest wywoływana, ale to chyba bez znaczenia.

Moje pytanie brzmi jak przekazać dane ze strumienia jako argument dla funkcji. Oczywistym rozwiązaniem byłoby utworzenie dodatkowej zmiennej pośredniczącej:
C/C++
std::string zmienaPosrednik;
obiekt1 >> zmiennaPosrednik;
obiekt2.funkcja( zmiennaPosrednik );

Ale wiąże się to z dodatkową alokacją pamięci, która jest niepotrzebna. Wartości tej zmiennej nie będę już potem potrzebował, więc rozwiązanie wydaje mi się słabe w kwestii optymalizacyjnej. Zna ktoś może sposób jak przekazać dane ze strumienia do funkcji jako argument, ale bezpośrednio?

Z góry dzięki za odpowiedź :)
P-171323
jankowalski25
» 2018-06-01 22:36:48
wskaźnik &
Nie wskaźnik, tylko referencja. Jak masz referencję, to musisz podpiąć tam jakąś zmienną. Czyli musisz zrobić coś w stylu:
C/C++
typ zmienna;
funkcja( zmienna );
Chyba że masz referencję do stałej, wtedy można takie coś zrobić w locie przez
funkcja( wyrazenie )
, ale właśnie po to masz wersję bez
const
, aby tam zapisać dane (czyli zmienić wartość).

rozwiązanie wydaje mi się słabe w kwestii optymalizacyjnej
Tym zwykle zajmie się kompilator, na optymalizacje przyjdzie jeszcze czas.

Zna ktoś może sposób jak przekazać dane ze strumienia do funkcji jako argument, ale bezpośrednio?
Na upartego można napisać własną wersję z
const
, gdzie utworzysz zmienną, wywołasz funkcję, zrobisz co trzeba z wynikiem i od razu wszystko zostanie zniszczone po wyjściu z takiej funkcji.

Dopisano:
Zresztą, referencje są dość dobrze optymalizowane i jeśli na przykład masz kilka referencji do tej samej zmiennej, to po prostu odwołujesz się do tej samej komórki pamięci używając innych nazw, a pamięć na same referencje nawet nie musi być przydzielana. Optymalizować kod zacznij dopiero wtedy, gdy będziesz miał coś, co działa za wolno, inaczej to zazwyczaj nie ma sensu.
P-171325
Doriak
Temat założony przez niniejszego użytkownika
» 2018-06-01 23:15:34
wskaźnik &
Nie wskaźnik, tylko referencja.
Ok, mój błąd.

Chyba że masz referencję do stałej, wtedy można takie coś zrobić w locie przez
funkcja( wyrazenie )
, ale właśnie po to masz wersję bez
const
, aby tam zapisać dane (czyli zmienić wartość).
I właśnie funkcja przyjmuje
const
:
void funkcja( const std::string & 2zmienna )

Czy w takim razie tak będzie poprawnie?
funkcja( strumien >> typ zmienna )
P-171326
jankowalski25
» 2018-06-01 23:39:15
I właśnie funkcja przyjmuje
const
Aj, namąciłem z tym przykładem, bo masz funkcję o nazwie funkcja. Chodziło o funkcję wczytującą dane ze strumienia. Ona nie może przyjmować
const
, skoro ma zapisać tam wczytane dane.

strumien >> typ zmienna
Nie. Nie można połączyć tego w ten sposób. Oddzielnie zadeklaruj zmienną i oddzielnie wczytaj dane do niej. A jeśli chcesz, aby została jak najszybciej zlikwidowana, to zawsze możesz utworzyć dodatkowy zasięg (wtedy po opuszczeniu zasięgu zostanie zniszczona) albo napisać oddzielną funkcję (wtedy po wyjściu z funkcji taka dodatkowa zmienna zostanie usunięta).
P-171327
YooSy
» 2018-06-01 23:40:38
Podaj pełną treść zadania. Wydaje mi się, że zadajesz niewłaściwe pytania.
P-171328
Doriak
Temat założony przez niniejszego użytkownika
» 2018-06-02 00:27:12
Nie mam żadnej funkcji wczytującej ze strumienia.

Chcę skorzystać z danych w strumieniu bez przypisywania ich do dodatkowej zmiennej. Moja funkcja o nazwie funkcja, która modyfikuje tylko obiekt, którego jest metodą, a nie dane wejściowe, pobierze sobie jako argument dane ze strumienia opróżniając go przy tym. To jest ich jedyne przeznaczenie, a po zakończeniu funkcji te dane znikają.

EDIT:
Albo inaczej chcę wyjście strumienia skierować na wejście funkcji, taki pipe.
P-171329
jankowalski25
» 2018-06-02 00:38:02
Nie mam żadnej funkcji wczytującej ze strumienia.
Klasa1 operator >>( std::string & 1zmienna )
To jest funkcja. Ma wartość zwracaną, nazwę i argumenty, więc jest niewątpliwie funkcją. Co prawda składnia jest nieco mniej typowa, bo to operator, ale można to wywołać również tak:
obiekt.operator >>( zmienna )
 (oczywiście zapis
obiekt >> zmienna
 jest prostszy i częściej stosowany w praktyce).

C/C++
std::string zmienaPosrednik;
obiekt1 >> zmiennaPosrednik;
obiekt2.funkcja( zmiennaPosrednik );
Co jest złego w tym rozwiązaniu, skoro i tak musisz utworzyć zmienną? Co najwyżej możesz dołożyć dodatkowe klamry (tworząc nowy zasięg), wtedy od razu po wyjściu z takiego bloku dodatkowa zmienna zostanie usunięta. A jak chcesz tego użyć w kilku miejscach, to możesz utworzyć nową funkcję, w której to umieścisz i wywoływać ją za każdym razem, gdy chcesz tego użyć (żeby uniknąć powtórzeń).

chcę wyjście strumienia skierować na wejście funkcji, taki pipe
Zależy od strumienia. Czasami można użyć do tego celu funkcji
rdbuf()
 (ale niekoniecznie wtedy, gdy masz własną klasę strumienia, bo takiej funkcji może tam po prostu nie być).
P-171330
Doriak
Temat założony przez niniejszego użytkownika
» 2018-06-02 02:01:50
Nie mam żadnej funkcji wczytującej ze strumienia.
Klasa1 operator >>( std::string & 1zmienna )
To jest funkcja. Ma wartość zwracaną, nazwę i argumenty, więc jest niewątpliwie funkcją. Co prawda składnia jest nieco mniej typowa, bo to operator, ale można to wywołać również tak:
obiekt.operator >>( zmienna )
 (oczywiście zapis
obiekt >> zmienna
 jest prostszy i częściej stosowany w praktyce).
No i git, wreszcie rozumiem. Rozumiem, że pytałem "co jest na północ od bieguna północnego?". A oczekiwałem między procesem pisania i czytania zabrać kartkę, a pisać bezpośrednio na oku...

chcę wyjście strumienia skierować na wejście funkcji, taki pipe
Zależy od strumienia. Czasami można użyć do tego celu funkcji
rdbuf()
 (ale niekoniecznie wtedy, gdy masz własną klasę strumienia, bo takiej funkcji może tam po prostu nie być).
O! Tego mi trzeba, ale niestety jest jak napisałeś, nie mam tego w mojej bibliotece :(

Dlatego pójdę za radą:
A jak chcesz tego użyć w kilku miejscach, to możesz utworzyć nową funkcję, w której to umieścisz i wywoływać ją za każdym razem, gdy chcesz tego użyć (żeby uniknąć powtórzeń).

Dzięki za pomoc :D I to tak szybką i fachową :o

EDIT:
Temat w sumie do zamknięcia.
P-171331
« 1 »
  Strona 1 z 1