Kai-Uwe Bux wrote:
[color=blue]
> Steven T. Hatton wrote:[/color]
[...]
[color=blue]
> You are thinking of some kind of two-faced type that will convert silently
> to either an int or a string so that a variable of that type could be used
> like so:
>
> Smart_Error_Code exit_code = some_function();
> std::cerr << exit_code << '\n';
> switch exit_code {
> case NO_RET : {...}
> ...
> }
>
> Here NO_RET would also be of type Smart_Error_Code. I played around with
> it for a little while, but I was not able to get the implicit conversion
> work out properly. Damn code would not compile.
>[/color]
Actually, I was combining a few such musings into a single design idea.
Probably a bad idea at this stage. The most important behavior would be
something such as:
MagicPair<int, std::string> mp(42, "SuSE Linux 4.2");
switch(key) {
case mp: return "The first version of SuSE Linux.";//as if mp===42;
}
std::cout<<mp<<std::endl;
// prints `SuSE Linux 4.2'
[color=blue][color=green]
>> It's the kind of thing that has often seemed marginally useful. Of
>> course the first place I want to use it is as an element in a
>> key_map<Key_T, Mapped_T>.[/color]
>
> Does not the two-faced type already represent the map? Obviously I am
> missing something.[/color]
Probably because my thinking, and hence my words are not clear. I want
something that I can easily print out in a for-each loop as key/value
pairs. The auto-conversion to std::string for the key was "additional
support". That would be for situations such as are dealt with by this bit
of code:
http://www.research.att.com/~bs/bs_f...#int-to-string
It would probably be sufficient to have something along the lines of
MagicPair<>::key_as_string();
[color=blue][color=green]
>> BTW, as counterintuitive as it may seem, the actual name given to the
>> type of the other half of a key-value pair in a std::map<> is as shown in
>> the following:
>>
>> namespace std {
>> template <class Key, class T, class Compare = less<Key>,
>> class Allocator = allocator<pair<const Key, T> > >
>> class multimap {
>> public:
>> typedef Key key_type;
>> typedef T mapped_type;
>> typedef pair<const Key,T> value_type;
>> //...
>> };
>> }[/color]
>
> You are right.
>
>
> BTW, I revisited the first posting. Here is a version of the dictionary
> that uses expression templates to unroll the checks at compile time. It
> could compile to something rather close to your original code:[/color]
[snip for further review]
Now I've done it! I opened my mouth, and now people are expecting me to
_think_! I'll take a closer look at your code before commenting on it.
I will observe that in another post you provided this:
value_type const & operator[] ( key_type const & key ) const {
typename map_type::const_iterator iter = data.find( key );
if ( iter != data.end() ) {
return( iter->second );
} else {
return( answer_default );
}
Which suggests you are aware of the gotcha related to std::map::operator[
(key) const;
This is my current hack to address the original issue:
template<typename K, typename M>
class KeyMap_T {
public:
typedef std::map<K,M> map_type;
KeyMap_T(const map_type& map_, const M& default_)
:_map(map_.begin(), map_.end())
,_default(default_)
{}
// Big dilemma: If I explicitly create a variable of iterator type, I avoid
// calling _map.find(k) twice. But I cannot accomplish that in one line of
// moderately sane code. I'm not sure which version an optimizer will
// prefer.
const std::string& operator[](const K& k) const {
return _map.find(k) != _map.end()? _map.find(k)->second: _default;
}
private:
map_type _map;
M _default;
};
//---------------------------------------
typedef KeyMap_T<Elf32_Word,std::string> Elf32_WordMap;
Elf32_WordMap::map_type mapSectionHeader();
const Elf32_WordMap sectionHeaderKeyMap(mapSectionHeader(),"UNKNOWN ");
// I had a KeyMap_T<>::add(const key_type& k, const mapped_type& m), but I
// wasn't using it, so I removed it. What I have may appear hackish, but it
// is the most comfortable version I came up with.
Elf32_WordMap::map_type mapSectionHeader() {
Elf32_WordMap::map_type m;
m[SHT_NULL] = "NULL ";
m[SHT_PROGBITS] = "PROGBITS";
m[SHT_SYMTAB] = "SYMTAB ";
m[SHT_STRTAB] = "STRTAB ";
m[SHT_RELA] = "RELA ";
m[SHT_HASH] = "HASH ";
m[SHT_DYNAMIC] = "DYNAMIC ";
m[SHT_NOTE] = "NOTE ";
m[SHT_NOBITS] = "NOBITS ";
m[SHT_REL] = "REL ";
m[SHT_SHLIB] = "SHLIB ";
m[SHT_DYNSYM] = "DYNSYM ";
return m;
}
I don't like the return by value, but the alternative is to create `m' in
the calling scope, which is a bother.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell