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
Пространство имен. Таким образом, компилятор будет искать там <<
оператор, а не в вашем пространстве имен.