typ variant

dział ogólny

typ variant

Nowy postprzez banita » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 01:52

Kod: Zaznacz cały
   Variant temp;
   TDateTime date = TDateTime().CurrentDate();
   temp = date; // typ variant przechowuje TDateTime
   TDateTime date2 = temp; // do date2 przypisujemy variant ktory faktycznie jest TDateTime

ten kod dziala.

natomisat to:
Kod: Zaznacz cały
class Test
{
   public:
      TDateTime t;
};

   Variant temp;
   TDateTime date = TDateTime().CurrentDate();
   temp = date; // typ variant przechowuje TDateTime
   Test date2;
   date2.t = temp; // do date2.t (ktore jest TDateTime) przypisujemy variant ktory faktycznie jest TDateTime


powoduje blad:

[BCC32 Error] Unit1.cpp(29): E2015 Ambiguity between '_fastcall operator System::TDateTime::=(const System::TDateTime &) at c:\program files\codegear\rad studio\5.0\include\vcl\systdate.h:58' and '_fastcall operator System::TDateTime::=(const double) at c:\program files\codegear\rad studio\5.0\include\vcl\systdate.h:60'


rozumiem co oznacza blad ale nie rozumiem czemu w przypadku 1 jest ok a w 2 juz nie.

czemu tak sie dzieje? problem wystepuje w C++Builder 2007.

przenosze projekt z TurboC++ (C++Builder 2006) gdzie obydwa przypadki dzialaja poprawnie do C++Builder 2007 i tutaj mam ten problem.

C++Builder 2007 zawiera wszystkie aktualizacje.


TDateTime jest tu przykladem, w przypadku AnsiString jest to samo. Dla zmiennych prostych wszystko gra bo tam nie ma konstruktorow.

EDIT:

typ Variant ma zdefiniowane operatory konwersji, miedzy innymi dla TDateTime.
to powinno wywolac owy operator ale tego nie robi.
Kod: Zaznacz cały
date2.t = temp;

dopiero jawne wywolanie operatora konwersji przechodzi:
Kod: Zaznacz cały
date2.t = temp.operator TDateTime();


czemu w pierwszym przedstawionym przypadku operator konwersji jest wywolywany niejawnie czyli tak jak powinno byc a w drugim juz nie?
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Cyfrowy Baron » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 09:03

Nie wiem jak to jest w Turbo C++, ale w C++ Builder musi to być wartość typu double a nie Variant:

to zadziała:
Kod: Zaznacz cały
class Test
{
   public:
      TDateTime t;
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   double temp;
   TDateTime date = TDateTime().CurrentDate();
   temp = date;
   Test date2;
   date2.t = temp;
   ShowMessage(FormatDateTime("dddd dd mmmm yyyy", date2.t));
}
//---------------------------------------------------------------------------


Jeżeli chcesz korzystać z typu Variant to musisz wywołać operator konwersji jawnie:

Kod: Zaznacz cały
class Test
{
   public:
      TDateTime t;
};
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Variant temp;
   TDateTime date = TDateTime().CurrentDate();
   temp = date; // typ variant przechowuje TDateTime
   Test date2;
   date2.t = VarToDateTime(temp);
   ShowMessage(FormatDateTime("dddd dd mmmm yyyy", date2.t));
}
//---------------------------------------------------------------------------


TDateTime jest tu przykladem, w przypadku AnsiString jest to samo. Dla zmiennych prostych wszystko gra bo tam nie ma konstruktorow.


Właściwie to sam sobie udzieliłeś odpowiedzi. Typ double jest prostą zmienną, a Variant już nie.

Tak też nie zadziała:
Kod: Zaznacz cały
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Variant temp;
   TDateTime date = TDateTime().CurrentDate();
   temp = date; // typ variant przechowuje TDateTime
   TDateTime date2;
   date2 = temp;
   ShowMessage(FormatDateTime("dddd dd mmmm yyyy", date2));
}
//--------------------------------------------------------------------------


Do zmiennej typu Variant można przypisać wartość typu TDateTime, ale do TDateTime nie można już przypisać niejawnie wartości typu Variant.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Witold » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 12:23

banita napisał(a):przenosze projekt z TurboC++ (C++Builder 2006) gdzie obydwa przypadki dzialaja poprawnie do C++Builder 2007 i tutaj mam ten problem.



Dziwne, u mnie pod Turbo 2006 wywala:
[C++ Error] Unit3.cpp(61): E2015 Ambiguity between '_fastcall System::TDateTime::operator =(const System::TDateTime &)' and '_fastcall System::TDateTime::operator =(const double)'


Podobnie pod bcb6/CB2010.

W pierwszym wypadku masz konstrukcję obiektu, w drugim przypisanie (przy nim występuje niejasność) - widać to ma znaczenie.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: typ variant

Nowy postprzez banita » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 15:19

dziwne. projekt napisany w TurboC++ (czyli c++builder 2006)ze wszystkmi aktualizacjami kompiluje mi obydwa przypadki z pierwszego postu. konkretnie funkcja pobiera dane z bazy i konkretne wartosci zwraca mi jako variant tak aby dowolne pole odbierac jedna funkcja.

co do konwersji w trakcie inicjalizacji badz przypisania to z punktu widzenia c++ w jednym i drugim przypadku powinno byc ok jezeli mamy zdefiniowany odpowiedni operator konwersji.
dziwne ze tutaj podczas inicjalizacji operator ten dziala a w przypadku przypisnaia nalezy go jawnie wywolac.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Witold » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 19:13

banita napisał(a):w jednym i drugim przypadku powinno byc ok jezeli mamy zdefiniowany odpowiedni operator konwersji.


Trochę danych aby było łatwiej się połapać:
Kod: Zaznacz cały
class TDateTime …
{
…
TDateTime& __fastcall operator =(const TDateTimeBase& rhs);
TDateTime& __fastcall operator =(const TDateTime& rhs);
TDateTime& __fastcall operator =(const double rhs);
TDateTime& __fastcall operator =(const int rhs);
….
};


Kod: Zaznacz cały
class Variant ….
{
….
operator double()
operator float()
operator int()
operator short()
operator TDateTime()
…
};


Kod: Zaznacz cały
...
Variant temp;
TDateTime date = TDateTime().CurrentDate();
temp = date; // typ variant przechowuje TDateTime
Test date2;
date2.t = temp; // do date2.t (ktore jest TDateTime) przypisujemy variant ktory faktycznie jest TDateTime


bcb wywala że nie wie do którego operatora dopasować:

TDateTime& __fastcall operator =(const TDateTime& rhs);
TDateTime& __fastcall operator =(const double rhs);


Czemu ma wybrać: TDateTime ::operator =(const TDateTime& rhs) i Variant ::operator TDateTime() ?
To też chyba pasuje: TDateTime :: operator =(const double rhs) i Variant ::operator double()
I to też : TDateTime :: operator =(const int rhs) i Variant ::operator int()
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: typ variant

Nowy postprzez Cyfrowy Baron » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 22:07

bcb wywala że nie wie do którego operatora dopasować:

TDateTime& __fastcall operator =(const TDateTime& rhs);
TDateTime& __fastcall operator =(const double rhs);


więc powinno wystarczyć:

Kod: Zaznacz cały
Variant temp;
TDateTime date = TDateTime().CurrentDate();
temp = date; // typ variant przechowuje TDateTime
Test date2;
date2.t = (TDateTime)temp; // lub (dounle)temp;


co się akurat zgadza, gdyż powyższy kod zadziała prawidłowo.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez banita » poniedziaÅ‚ek, 7 wrzeÅ›nia 2009, 23:25

no wlasnie... powinno wystarczyc a jednak nie.
pojawia sie komunikat bledu:

[BCC32 Error] Unit1.cpp(31): E2015 Ambiguity between '_fastcall System::TDateTime::TDateTime(const System::TDateTime &) at c:\program files\codegear\rad studio\5.0\include\vcl\systdate.h:44' and '_fastcall System::TDateTime::TDateTime(const double) at c:\program files\codegear\rad studio\5.0\include\vcl\systdate.h:45'

[BCC32 Error] Unit1.cpp(31): E2031 Cannot cast from 'Variant' to 'TDateTime'


i to jest zastanawiajace.
gdy zamiast:
Kod: Zaznacz cały
date2.t = (TDateTime)temp;

damy:
Kod: Zaznacz cały
date2.t = temp.operator TDateTime();

to juz dziala.

z punku widzenia c++ obydwa zapisy sa rownowazne wiec moim zdaniem c++builder tutaj grubo odbiega od standardu.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Witold » wtorek, 8 wrzeÅ›nia 2009, 00:52

banita napisał(a):i to jest zastanawiajace.
gdy zamiast:
Kod: Zaznacz cały
date2.t = (TDateTime)temp;

damy:
Kod: Zaznacz cały
date2.t = temp.operator TDateTime();

to juz dziala.

z punku widzenia c++ obydwa zapisy sa rownowazne wiec moim zdaniem c++builder tutaj grubo odbiega od standardu.


Najwyraźniej nie. Wydaje mi się że date2.t = (TDateTime)temp; powoduje że kompilator zaczyna szukać konstruktora TDateTime przy pomocy którego można przeprowadzić konwersje Variant -> TDataTime, pasują mu dwa/lub więcej. Błąd. Ciekawe jest to na BCB6, nie ma błędu, pewnie wynika to z niezgodności z std.

Przy jawnym wywołaniu operatora nie ma wątpliwości.

Banita, mógłbyś załączyć projekt z Turbo C++ 2006 z tymi przypadkami z pierwszego postu, który się u ciebie nie wywala błędów.
Avatar użytkownika
Witold
Konstrukcjonista
Konstrukcjonista
 
Posty: 223
Dołączył(a): piątek, 29 sierpnia 2008, 10:53
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 14
Kompilator: bcb6, Turbo C++ Explorer
    NieznanyNieznana

Re: typ variant

Nowy postprzez banita » wtorek, 8 wrzeÅ›nia 2009, 01:36

niestety ale dosc duzy projekt, kilkaset plikow itd... ale fragment dotyczy np:

Kod: Zaznacz cały
Variant CustomQuery::GetCurrentValue(String field_name)
{
   return query_->FieldByName(field_name)->Value;
}

gdzie query_ to ADOQuery.
dalej...


Kod: Zaznacz cały
               temp.id_msg = query->GetCurrentValue("id_zlecenia");
               temp.name = query->GetCurrentValue("imie");
               temp.surname = query->GetCurrentValue("nazwisko");
               temp.personal_identity_number = query->GetCurrentValue("pesel");
               temp.number = query->GetCurrentValue("numer");
               temp.date = query->GetCurrentValue("data");

gdzie temp.date to TDateTime

to tylko przyklad ktory najszybciej znalazlem.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Cyfrowy Baron » wtorek, 8 wrzeÅ›nia 2009, 11:48

Przypisanie TDataTime rzeczywiście nie działa, ale można zastosować przypisanie double, efekt będzie zgodny z oczekiwaniami:

Kod: Zaznacz cały
Variant temp;
TDateTime date = TDateTime().CurrentDate();
temp = date; // typ variant przechowuje TDateTime
Test date2;
date2.t = (dounle)temp;


Zachodzi tutaj chyba podwójna konwersja, gdyż najpierw typ Variant jest przypisany do double, a potem jest przypisywany, już double jest przypisywane do TDataTime. To już zadziała.

Dlaczego upierasz się przy typie Variant skoro od razu można zastosować typ double?!

Kod: Zaznacz cały
double temp;
TDateTime date = TDateTime().CurrentDate();
temp = date; // typ double przechowuje TDateTime
Test date2;
date2.t = temp;
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez banita » wtorek, 8 wrzeÅ›nia 2009, 14:11

nie upieram sie;)

problem w tym ze nie pisze tego od podstaw, caly projekt jest gotowy.

Kod: Zaznacz cały
Variant CustomQuery::GetCurrentValue(String field_name)
{
   return query_->FieldByName(field_name)->Value;
}

to metoda klasy(wrappera) na ADOQuery i w calym projekcie miejsc typu:
temp.date = query->GetCurrentValue("data");

jest kilkaset.

problemu w ogole by nie bylo gdybym pisal od podstaw.
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez Cyfrowy Baron » wtorek, 8 wrzeÅ›nia 2009, 14:17

Czy nie możesz zmodyfikować tej klasy?

Może mógłbyś zrobić to tak:
Kod: Zaznacz cały
temp.date = (double)query->GetCurrentValue("data");
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: typ variant

Nowy postprzez banita » wtorek, 8 wrzeÅ›nia 2009, 14:49

przy tych przypisaniach wywoluje jawnie operator konwersji tyle ze jest tego duzo:) no ale coz skoro trzeba to trzeba
Avatar użytkownika
banita
Kreacjusz
Kreacjusz
 
Posty: 283
Dołączył(a): poniedziałek, 28 lipca 2008, 20:07
PodziÄ™kowaÅ‚ : 1
OtrzymaÅ‚ podziÄ™kowaÅ„: 18
System operacyjny: Windows 7 Professional
Kompilator: C++Builder 2010 Update 5,
Delphi 2010 Update 5,
NetBeans 6.9(MinGw + Qt),
Visual Studio 2008 + Qt
Gadu Gadu: 0
    NieznanyNieznana


Powrót do Ogólne problemy z programowaniem

Kto przeglÄ…da forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 4 gości