Thursday, 21 September 2017

c++ - Ambiguous overloading with operator[] and operator int()



I am creating a class Item, and each Item is a key/value pair. Also, each Item may also contain subitems:



#include 
#include
#include



class Item
{
private:
std::string key;
unsigned int value;

std::vector subitems;


public:

Item( const std::string& key = "", const int& value = 0 )
: key( key ), value( value ){ };


public:
// Search or Create new SubItem.
Item& operator[]( const std::string& key )
{
for( auto& subitem : subitems )
if( subitem.key == key )

return subitem;

subitems.push_back( Item( key ));
return subitems.back( );
}


public:
// Assign new value to Item.
Item& operator=( const int& value )

{
this->value = value;
return *this;
}


public:
// Get value from Item.
operator unsigned int( ) const
{

return value;
}
};



int main( void )
{
Item item;



item["sub"] = 42;
unsigned int sub = item["sub"];


std::cout << std::to_string( sub ) << std::endl;
return 0;
}



When I try to compile this, I get:



error: ambiguous overload for ‘operator[]’ (operand types are ‘Item’ and ‘const char [4]’)



If I create a member method unsigned int Get() instead of operator int() it does compile. But I wanted the class to work the same way that std::map works:



#include 
#include
#include




int main( void )
{
std::map item;


item["sub"] = 42;
unsigned int sub = item["sub"];



std::cout << std::to_string( sub ) << std::endl;
return 0;
}


How can I get it working?
Thanks!


Answer



The problem is that you are conflicting with the builtin operator[](unsigned int, const char *) (yes, that's a thing).




Implicitely converting the operand to a std::string or implicitely converting the Item to an unsigned int before applying the operator[] is equivalent for the compiler, so it can't choose between the two.



You can work around this by adding an explicit const char* overload to your class' operator[] that defers to your std::string implementation.



// Search or Create new SubItem.
Item& operator[]( const char* key ) {
return (*this)[std::string(key)];
}


No comments:

Post a Comment

casting - Why wasn&#39;t Tobey Maguire in The Amazing Spider-Man? - Movies &amp; TV

In the Spider-Man franchise, Tobey Maguire is an outstanding performer as a Spider-Man and also reprised his role in the sequels Spider-Man...