ADL не может найти оператор потока с соответствующими квалификаторами для определенного пользователем типа

Я собираю службу x64 в Microsoft Windows 7 с Visual Studio 2010, используя вариант Boost, что-то вроде:

namespace my_ns
{
    typedef struct {} empty_t;
    typedef std::pair<size_t, std::shared_ptr<char>> string_t;
    typedef boost::variant<empty_t, double, long, string_t> variant_t;
    typedef std::map<unsigned short, variant_t> variant_map_t;
}

День, когда я избавляюсь от этого string_t и заменяю его std::string, является днем, когда я покупаю своего босса и пончики команды. Но это не то, почему мы здесь...

Вариант Boost поддерживает операторы потока для его содержащихся типов при условии, что тип перегружен. Так что я:

namespace my_ns
{
    std::ostream &operator<<(std::ostream &, const empty_t &);
    std::ostream &operator<<(std::ostream &, const string_t &);
}

И все же меня мучает сообщение об ошибке:

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'const T3' (or there is no acceptable conversion)

T3 ссылается на string_t.

Код, создающий ошибку, существует в следующем контексте. Это многословно, так что вы, читатель, имеете соответствующую контекстную информацию:

namespace my_ns
{
    void Widget::public_method(std::ostringstream &os) const
    {
        //variant_map_t Widget::the_map; // Private Widget member.

        // This here is a C++11 lambda in a standard loop algorithm, if you didn't recognize the syntax.
        std::for_each(the_map.begin(), the_map.end() [&os](variant_map_t::value_type value)
        {
            os << value.first << '=' << value.second << ' ';
        });
    }
}

Я попытался удалить правые квалификаторы и ссылку, думая, что передача копии по значению отбросит квалификаторы (вероятно, не так уж и блестяще в свете общего указателя), и я попытался переместить объявления из пространства имен в глобальную область видимости, надеясь, что ADL по какой-то причине его поднимет (концептуально я получаю ADL, но для меня все еще остается немного чёрной магии).

Я не знаю, что еще делать. Какова природа этой ошибки за пределами того, что компилятор не может найти оператор вставки с константным rhs? Как это может быть, когда это прямо там? И какое разрешение?

1 ответ

Это не помогает, что вы добавляете typedef к вашему пространству имен, std::pair а также std::ostream все еще являются частью std Пространство имен. Таким образом, компилятор будет искать там << оператор, а не в вашем пространстве имен.

Другие вопросы по тегам