By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,866 Members | 1,704 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,866 IT Pros & Developers. It's quick & easy.

What are those _Traits for?

P: n/a
Hi all.

I can see the standard template library has changed a lot since I begun C++
10 years ago...

Now I'm facing with outputing the members of a struct, say Option, which
contains 2 members through ostream. I have defined a vector of Option:

struct Option {
char* name;
int value;
};

typedef vector<Optionovect;

....

int main()
{
ovect v();
ovect.reserve(10);
...
// Add elements to the vector
cout << v[0];
...
return 0;
}

When I compile (in Bloodshed Dev-C++) I get zillions of errors like:

main.cpp:85: error: no match for 'operator<<' in 'std::operator<< [with
_Traits = std::char_traits<char>](((std::basic_ostream<char,
std::char_traits<char&)(+(+std::operator<< [with _CharT = char, _Traits
= std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char>
>&)(&std::cout)), std::setw(4)))->std::basic_ostream<_CharT,
_Traits>::operator<< [with _CharT = char, _Traits = std::char_traits<char>
(i))), ((const char*)" ")) << ((const std::vector<gnu_opt,
std::allocator<gnu_opt*)(+v))->std::vector<_Tp, _Alloc>::operator[]
[with _Tp = gnu_opt, _Alloc = std::allocator<gnu_opt>](i)'

C:/dev/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/ostream.tcc:63:
note: candidates are: std::basic_ostream<_CharT, _Traits>&
std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT,
_Traits>&(*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char,
_Traits = std::char_traits<char>]
....
C:/dev/Dev-Cpp/Bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/ostream.tcc:74:
note: std::basic_ostream<_CharT, _Traits>&
std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT,
_Traits>&(*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char,
_Traits = std::char_traits<char>]

I've digged into the iostream library and I must admit there is nothing like
I used to know about that library before, everything has changed :( .
Especially I can't figure out what the typename _Traits is for in standard
template library templates. I can see _Traits in strings, ostreams,
istreams, aso.

I guess I need to create an operator "<<" for my structure but I have no
idea of what it should look like.

Thanks for any hint/suggestion.

--

Vince C.
Jul 15 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Vince C. wrote:
Hi all.

I can see the standard template library has changed a lot since I begun
C++ 10 years ago...

Now I'm facing with outputing the members of a struct, say Option, which
contains 2 members through ostream. I have defined a vector of Option:

struct Option {
char* name;
int value;
};

typedef vector<Optionovect;

...

int main()
{
ovect v();
That does not declare a vector but a function.
ovect.reserve(10);
v.reserve(10);
...
// Add elements to the vector
cout << v[0];
...
return 0;
}

When I compile (in Bloodshed Dev-C++) I get zillions of errors like:
[snip]
I've digged into the iostream library and I must admit there is nothing
like I used to know about that library before, everything has changed :( .
Especially I can't figure out what the typename _Traits is for in standard
template library templates. I can see _Traits in strings, ostreams,
istreams, aso.

I guess I need to create an operator "<<" for my structure but I have no
idea of what it should look like.

Try something like this:

#include <iostream>
#include <ostream>
#include <vector>

struct Option {
char* name;
int value;
};

std::ostream & operator<< ( std::ostream & ostr,
Option const & opt ) {
ostr << opt.name << " : " << opt.value;
return ( ostr );
}
typedef std::vector<Optionovect;
int main()
{
ovect v;
v.reserve(10);
Option opt;
opt.value = 1;
opt.name = "name";
v.push_back( opt );
std::cout << v[0] << '\n';
}

BTW: you should consider using std::string instead of char*.
Best

Kai-Uwe Bux
Jul 15 '07 #2

P: n/a
Kai-Uwe Bux wrote:
Vince C. wrote:
....
Kai-Uwe Bux
Thanks a lot. In fact I made an error while defininig operator <<, which
second argument was not Option const but vector<Option>... That could not
work, of course. Now it does.

Thanks again for your help.

Note I still don't know what the _Traits are for in templates... What is
their purpose? (Just out of curiosity.)

--

Vince C.
Jul 15 '07 #3

P: n/a
On Jul 16, 12:41 am, "Vince C." <n...@teledisnet.bewrote:
Kai-Uwe Bux wrote:
Vince C. wrote:
...
Kai-Uwe Bux
Thanks a lot. In fact I made an error while defininig operator <<, which
second argument was not Option const but vector<Option>... That could not
work, of course. Now it does.
Thanks again for your help.
Note I still don't know what the _Traits are for in templates... What is
their purpose? (Just out of curiosity.)
In the case of iostream, to add complexity, and make
implementation more difficult. They're not very useful
otherwise.

In general, the concept of traits can be used to provide complex
additional information to a template, with default values.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 16 '07 #4

P: n/a
Kai-Uwe Bux wrote:
Generally, traits classes carry information about types. [...]

Now, the CharT is the underlying type for the characters in the string.
Usually, that would be char, unsigned char or something like wchar_t. Some
operations are not hard-coded into the basic_string template, instead they
are parameterized. For instance all memory allocation and deallocation is
done through Alloc.

The Traits parameter, in this case, provides a hook for the user to tell
basic_string which C-string functions to use. [...]

Kai-Uwe Bux
Thanks a lot for that information, Kai-Uwe. That seems much clearer now.

To check if I understood, you need Traits whenever you need to optimize
operations provided by the basic class, according to the item type of a
vector, for instance?

In the string example you gave, there could be Traits for wide strings that
use the wide char version of string functions, is that correct? While there
would be Traits for char* that use the single byte functions, am I still
in? This allows for writing template member functions that optimize the
code according to the type, correct?

If I have understood, Traits have the benefical effect of not to rewrite the
whole template if the type changes *and* the way items are handled (copy,
compare, length, aso) but only the set of basic operations the base
template needs. Do I still follow?

So if I want a vector which elements are structures, I'd be better off
writing a Traits for that structure, too, wouldn't I?

--

Vince C.
Jul 16 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.