 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
greenuri Guest
|
Posted: Fri Mar 18, 2005 2:08 pm Post subject: [Nuri] Template class Error Some one help me |
|
|
hi there
I use stl map.
The map is very good to use.
So i want to use it template class
class definition is this
//--------------------------------------------------------------------------
-
template <class T1 , class T2>
class TTreeList
{
public :
inline T2& __fastcall operator[](const T1 t)
{
return data_[t];
}
inline T2& __fastcall operator[](const T1 t ) const
{
return data_[t] const;
}
inline map< T1 , T2 >::iterator __fastcall operator= (map<T1 ,
T2>::iterator);
inline AnsiString __fastcall GetText ( void );
__property map<T1,T2> Data = {write = data_, read=data_};
private :
map< T1 , T2 > data_;
};
//--------------------------------------------------------------------------
-
AnsiString __fastcall TTreeList<AnsiString,AnsiString>::GetText ( void )
{
AnsiString Result="";
map< AnsiString , AnsiString >::iterator mapitr;
for ( mapitr = data_.begin() ; mapitr != data_.end() ; mapitr++ )
{
Result += AnsiString(mapitr->first) + "=" + AnsiString(mapitr->second)
+ "r";
}
return Result;
}
//--------------------------------------------------------------------------
-
AnsiString __fastcall TTreeList<AnsiString,WTChargedAppList>::GetText (
void )
{
AnsiString Result;
int i = 0;
map < AnsiString , WTChargedAppList >::iterator mapitr;
for ( mapitr = data_.begin() ; mapitr != data_.end() ; mapitr++,i++ )
{
Result += "ChargedApp" + IntToStr(i) + "=" +
AnsiString(mapitr->second.ExeName) + char(13);
}
return Result;
}
//--------------------------------------------------------------------------
-
And i Use this template Class
typedef TTreeList<AnsiString , AnsiString > A_STR_TLIST;
A_STR_TLIST stl_ClientEnv;
A_STR_TLIST stl_ServerEnv;
TTreeList< AnsiString , WTChargedAppList > Charge_Content_Map;
But
stl_ClientEnv.GetText();
stl_ServerEnv.GetText();
Charge_Content_Map.GetText();
this 3 line has error
[Linker Error] Unresolved external '__fastcall TTreeList<System::AnsiString,
System::AnsiString>::GetText()' referenced from S:EZCLICKFRMMAIN.OBJ
What is wrong in this template class definition?
plz some one help me
|
|
| Back to top |
|
 |
Chris Uzdavinis (TeamB) Guest
|
Posted: Fri Mar 18, 2005 3:05 pm Post subject: Re: [Nuri] Template class Error Some one help me |
|
|
"greenuri" <greenuri (AT) pmbinfo (DOT) com> writes:
| Quote: | template <class T1 , class T2
class TTreeList
{
public :
inline T2& __fastcall operator[](const T1 t)
{
return data_[t];
}
inline T2& __fastcall operator[](const T1 t ) const
{
return data_[t] const;
}
|
You should be passing t by reference-to-const rather than by value, or
else a needless copy is being made. If T1 is an int, it's no harm,
but if it's a string or other more complicated type of key, it's
wasteful.
| Quote: | inline map< T1 , T2 >::iterator __fastcall operator= (map<T1 ,
T2>::iterator);
inline AnsiString __fastcall GetText ( void );
__property map<T1,T2> Data = {write = data_, read=data_};
private :
map< T1 , T2 > data_;
};
|
I'd strongly suggest you avoid adding properties to non VCL classes.
Also note, your Data property is returning a copy of the map. This is
an expensive operation. For efficiency, you should return a reference
here too. However, exposing the map directly to callers is breaking
encapsulation, and locks you into an implementation. (That is, your
interface returns map iterators and maps, so you are stuck using a
map, and cannot change the underlying implementation to, say, a hash
table, without breaking your interface.)
| Quote: | //--------------------------------------------------------------------------
-
AnsiString __fastcall TTreeList<AnsiString,AnsiString>::GetText ( void )
{
AnsiString Result="";
map< AnsiString , AnsiString >::iterator mapitr;
for ( mapitr = data_.begin() ; mapitr != data_.end() ; mapitr++ )
{
Result += AnsiString(mapitr->first) + "=" + AnsiString(mapitr->second)
+ "r";
}
return Result;
}
|
You are not writing the primary template, but just a specialization
for a particular value of T1 and T2. If T1 or T2 are anything other
than AnsiString, the above function shouldn't be considered. Since
your class is templatized on T1,T2, you should provide a definition
for the case where you don't know T1 and T2:
template <class T1, class T2>
inline AnsiString __fastcall GetText<T1, T2> ( void )
{
// do something.
}
Note, this function, when called, places a restriction on the valid
types for T1 and T2 used to instantiate your class. The requirement
is: Both types must be convertable to an AnsiString.
Also, the code you wrote, as shown above, is inefficient for several
reasons. You should pre-calcucate the end iterator instead of
recalculating it each iteration. You should always use pre-increment
instead of post-increment when you only want the side-effects and you
disregard the return value (like here.) But more importantly, you're
creating several needless AnsiString temporaries, each requiring the
data of the previous to be copied into the temporary.
| Quote: | What is wrong in this template class definition?
|
You only defined a specialization of the function class
--
Chris (TeamB);
|
|
| Back to top |
|
 |
Alisdair Meredith [TeamB] Guest
|
Posted: Fri Mar 18, 2005 3:23 pm Post subject: Re: [Nuri] Template class Error Some one help me |
|
|
greenuri wrote:
| Quote: | template <class T1 , class T2
class TTreeList
{
public :
inline T2& __fastcall operator[](const T1 t)
{
return data_[t];
}
inline T2& __fastcall operator[](const T1 t ) const
{
return data_[t] const;
}
inline map< T1 , T2 >::iterator __fastcall operator= (map<T1 ,
T2>::iterator);
inline AnsiString __fastcall GetText ( void );
__property map<T1,T2> Data = {write = data_, read=data_};
private :
map< T1 , T2 > data_;
};
|
This class has several problems, some of them cosmetic, some
significant.
First, I would not use Borland extensions when designing classes that
do not depend on the VCL. They are less clearly defined than standard
C++, making bug reporting difficult. They also limit the portability
of your code to other compilers, which may not be an issue today but I
find testing code on several compilers turns up many subtle errors that
any one compiler might allow.
So I suggest dropping the property and the __fastcall convention. In
particular, __property does not work very well with C++ class types.
Next look at this member:
| Quote: | inline T2& __fastcall operator[](const T1 t ) const
{
return data_[t] const;
}
|
The const in the return statement is just wrong.
I suspect you wnat to return a const reference to T2 as the return
type, and probably take T1 as a reference-to-const.
The important thing to understand though is that std::map does not have
a const overload for operator[] - by default if you ask for an element
not yet in the map a new item is automatically inserted for you. This
is hard to do in a const member ;?)
You shouldcall data_.find( t ) instead, and return the second element
of the std::pair on the other end of the iterator.
Don't forget to compare the iterator with data_.end() though, to allow
for not finding the element. Then you need to add some error handling
- normally I throw an exception when this happens.
AlisdairM(TeamB)
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|