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

Zapisanie typu zmiennej do innej zmiennej

Ostatnio zmodyfikowano 2019-02-08 13:20
Autor Wiadomość
ziajek444
Temat założony przez niniejszego użytkownika
Zapisanie typu zmiennej do innej zmiennej
» 2019-02-05 16:10:46
Witam,
Czy istnieje możliwość zapisanie typu zmiennej tak aby móc coś z tym typem później zrobić. Przykładowo rzutować na ten typ.

Prosta klasa dla zobrazowania przykładu (uwaga przykład jest nie poprawny !! )

C/C++
#include <typeinfo>
#include <iostream>

class A
{
public:
    int liczba;
    std::type_info & typ_zmiennej;
    template < typename T1 >
    A( T1 input ) {
        liczba = 999;
        typ_zmiennej = typeid( T1 ); // złe rozwiązanie, ale pokazuje do czego dążę.
    }
    void KonwesjaJawna()
    {
        std::cout <<( typ_zmiennej ) liczba << std::endl; // zakładam że typ typ_zmiennej ma zaimplementowany operator<<
    }
};

i teraz przykład użycia który chce osiągnąć

C/C++
int main()
{ double d = 2.4;
    A a( d );
    a.KonwersjaJawna(); // powinno wysietlic wartość równą (double)999;
    return 0;
}

P-173862
Monika90
» 2019-02-05 19:38:53
Można to osiągnąć techniką zwaną type erasure, tylko po co to chcesz zrobić?
P-173865
ziajek444
Temat założony przez niniejszego użytkownika
» 2019-02-05 20:12:54
Dziękuję Moniu za odpowiedź.
Spodziewałem się odpowiedzi że się nie da, dlatego już się biorę za przegląd googla pod kątem haseł "type erasure".
Czy możesz polecić jakieś ciekawe źródło? (koniecznie polskie lub angielskie)
Jeżeli tak i jest to artykuł, dokumentacja lub film to bardzo proszę o linka.
Jeżeli tak i jest to książka to poprosił bym o tytuł i ewentualnie autora.
Jeżeli nie to nic, i tak będę szukał na własną rękę.
P-173866
Monika90
» 2019-02-05 20:27:35
Samego rzutowania się nie da zrobić, ale da się zrobić drukowanie rzutowanej wartości. Przykład:
C/C++
#include <iostream>
#include <memory>

struct Print
{
    virtual void print( int ) const = 0;
    virtual ~Print() { }
};

template < class T >
struct PrintT
    : Print
{
    void print( int x ) const override { std::cout << static_cast < T >( x ) << std::endl; }
};

class A
{
public:
    int liczba;
    std::unique_ptr < Print > print;
    template < typename T1 >
    A( T1 input )
        : print( std::make_unique < PrintT < T1 >>() )
    {
        liczba = 999;
    }
    void KonwersjaJawna()
    {
        print->print( liczba );
    }
};

int main()
{ double d = 2.4;
    A a( d );
    std::cout << std::fixed;
    a.KonwersjaJawna(); // powinno wysietlic wartość równą (double)999;
    return 0;
}
P-173867
ziajek444
Temat założony przez niniejszego użytkownika
» 2019-02-06 12:23:32
Poczytałem trochę o type erasure.
Okazuje się że próbowałem mój problem rozwiązać w podobny sposób wcześniej, tylko klasę abstrakcyjna (bazową) i generyczna (dziedziczącą) miałem stworzoną poza klasa główną. No i nie używałem smart pointera.
Twoje rozwiązanie rozwiązuje przykładowy problem który podałem, ale to jest przykład w którym "główna zmienna" (dla type erasure byłby to smart pointer) jest zawsze int'em. Dlatego troszkę ją przerobiłem.
C/C++
template < typename T4, typename T5 >
void printToConsole( T4 typ, T5 wartosc )
{
    std::cout << static_cast < T4 >( wartosc );
}

Myślę że jak połączę obie techniki (type erasure + zewnętrzna funkcja obsługująca strumień) uzyskam zadowalający efekt.

Aby Temet nie trafił do śmieci, wstawię przykładową kombinację stanowiącą szkielet do pracy.
C/C++
class Object {
    struct ObjectConcept {
        virtual void T_print_() = 0;
        virtual ~ObjectConcept() { }
    };
   
    template < typename T > struct ObjectModel
        : ObjectConcept
    {
        ObjectModel( const T & t )
            : object( t )
        { }
        virtual void T_print_()
        {
            printToConsole( object, object );
        }
        virtual ~ObjectModel() { }
    private:
        T object;
    };
   
    std::shared_ptr < ObjectConcept > object;
   
public:
    template < typename T > Object( const T & obj )
        : object( new ObjectModel < T >( obj ) )
    { }
    void T_print_()
    {
        object->T_print_();
    }
};

Bazowy kod mojego szkieletu oraz sposoby jego rozbudowy można znaleźć tutaj:
["C++ type erasure" href="http://www.cplusplus.com/articles/oz18T05o/"]

//
Dziękuję bardzo za pomoc Monia,
Mam nadzieję że komuś sie przyda ten Temat.

P.S.
Gdzie zaczerpnęłaś wiedzę o type erasure. Nigdy się na to nie natknąłem.
P-173884
Monika90
» 2019-02-08 13:20:51
Nie wiem skąd wiem o type erasure, nie pamiętam. boost::any czy std::function tego używają w takiej lub innej postaci, bo dziedziczenie to nie jest jedyny sposób by osiągnąć type erasure.
P-173923
« 1 »
  Strona 1 z 1