Я хотел бы перегрузить оператор <<, чтобы он мог работать с <code>shared_ptr.
template<typename T>
struct foo
{
virtual foo& operator<<(const T& e) = 0;
};
foo<int> f1;
f1 << 1;
std::shared_ptr<foo<int>> f2(new foo<int>());
f2 << 1;
Моя первая попытка заключается в следующем, но проблема в том, что он также включает поведение длялюбой класс.
template<typename T, typename U>
const std::shared_ptr<T>& operator<<(const std::shared_ptr<T>& o, const U& e)
{
*o << e;
return o;
}
Моя вторая попытка следующая:
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const U& e)
{
*o << e;
return o;
}
Проблема с этим решением не работает для типов, наследующих foo, поскольку T
не может быть автоматически выведен.
Таким образом, я мог бы пропустить U
и использовать вместо него T
, и в этом случае T будет выведен из второго аргумента, а аргумент для o
можно преобразовать в foo<T>
.
template<typename T, typename U>
const std::shared_ptr<foo<T>>& operator<<(const std::shared_ptr<foo<T>>& o, const T& e)
{
*o << e;
return o;
}
Но тогда не сработает следующее:
struct c
{
};
struct a
{
a();
a(c); // implicit conversion
};
struct b
{
operator a(); // implicit conversion
};
auto f = std::make_shared<foo<a>>();
f << c; // doesn't work.
f << b; // doesn't work.
Есть идеи, как сделать рабочее решение?