Неоднозначная перегрузка с помощью operator [] и operator int () - PullRequest
1 голос
/ 28 октября 2019

Я создаю класс Item, и каждый Item является парой ключ / значение. Кроме того, каждый элемент может также содержать подэлементы:

#include <string>
#include <vector>
#include <iostream>


class Item
{
    private:
        std::string key;
        unsigned int value;
        std::vector<Item> 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;
}

Когда я пытаюсь скомпилировать это, я получаю:

ошибка: неоднозначная перегрузка для 'operator []' (типы операндовявляются 'Item' и 'const char [4]')

Если я создаю метод-член unsigned int Get () вместо operator int () это компилируется. Но я хотел, чтобы класс работал так же, как работает std :: map:

#include <map>
#include <string>
#include <iostream>



int main( void )
{
    std::map<std::string, unsigned int> item;


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


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

Как мне заставить его работать? Спасибо!

1 Ответ

3 голосов
/ 28 октября 2019

Проблема в том, что вы конфликтуете со встроенным operator[](unsigned int, const char *) (да, это так).

Неявное преобразование операнда в std::string или косвенное преобразование Item в unsigned int перед применением operator[] эквивалентно для компилятора, поэтому он не может выбирать между двумя.

Вы можете обойти эту проблему, добавив явную перегрузку const char* к своему классу 'operator[], которая относится к вашей реализации std::string.

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