Помимо здоровой критики в комментариях, давайте рассмотрим, что здесь происходит:
std::istream &ss = (choice == 'f') ? f : std::cin;
while (ss >> a)
istreame
ссылка ss
вызывает operator>>(int &)
(ADL в стороне).Таким образом, даже если ss
указывает на ваш класс Factory
(который по идее не является фабрикой), он все равно будет вызывать свой базовый оператор, поэтому выбор f
никогда не будет работать.
Если вы хотеличтобы достичь того, что вы намеревались, тогда operator>>
должно быть определено полиморфно (объявлено как virtual
) в базовом классе.Но это не так.
Таким образом, ваш подход терпит неудачу.Если вы хотите добиться демультиплексирования вашего класса (выступая в качестве потока) и других основанных на std::istream
(только для вашего случая), то подход должен быть переработан в нечто вроде следующего:
#include <sstream>
#include <iostream>
class Factory {
int count;
std::istream * is_ptr;
static std::stringstream dummy;
public:
Factory(std::istream &is = dummy): count{0}, is_ptr(&is) {}
operator bool(void) { return count < 5; }
Factory & operator>>(int &x) {
if(is_ptr == &dummy) // it's me being called
{ x = count++; return *this; }
*is_ptr >> x; // otherwise, calling a proxy
return *this;
}
};
std::stringstream Factory::dummy;
int main(int argc, char *argv[]) {
int a;
Factory f, c(std::cin);
char choice;
std::cout << "Read from (c)in or (f)actory?\n";
std::cin >> choice;
//choice = 'f';
Factory &ss = (choice == 'f') ? f : c;
while (ss >> a)
std::cout << "a = " << a << std::endl;
return 0;
}
Выводыс выбором 'f':
Read from (c)in or (f)actory?
f
a = 0
a = 1
a = 2
a = 3
bash $
Выходы с выбором 'c':
Read from (c)in or (f)actory?
c
123
a = 123
098765
a = 98765
^C
bash $