Почему оператор шаблона ‹< не выводит std :: endl?

Это будет скомпилировано и запущено, если вы раскомментируете первое определение оператора:

#include <iostream>

struct logger
{
    std::ostream &loggingStream;
    logger(std::ostream &ls) : loggingStream(ls) {}

};

/*
logger &operator<<(logger &l, std::ostream & (*manip)(std::ostream &)) {
    manip(l.loggingStream);
    return l;
}
*/

template<typename T>
logger &operator<<(logger &l, const T &t) {
    l.loggingStream << t;
    return l;
}

int main() {
    logger l(std::cout);

    l << "Hello" << std::endl;
    return 0;
}

С добавленным комментарием:

error: no match for ‘operator<<’ (operand types are ‘logger’ and ‘<unresolved overloaded function type>’)

Почему мне нужно предоставлять перегрузку без шаблона для обработки endl?


person spraff    schedule 06.03.2019    source источник
comment
1 / см. stackoverflow.com/q/1134388/136208 2 / создание настраиваемого streambuf - это способ, которым спроектирована подсистема ввода-вывода для такого рода пристройки   -  person AProgrammer    schedule 06.03.2019


Ответы (2)


std::endl сам по себе является шаблоном. Когда у вас есть первая перегрузка, ее аргументы могут быть выведены путем сопоставления с указателем функции. Потому что это один из примеров, когда случается ТАД.

Из чего можно делать выводы, используя только шаблон operator<<? Оба шаблона нуждаются в выводе своих аргументов.

person StoryTeller - Unslander Monica    schedule 06.03.2019

Поскольку в качестве шаблона функции std::endl является набором перегрузки с учетом к вычету аргумента шаблона; и вывод аргументов шаблона не может работать с наборами перегрузки (если, конечно, он не содержит только одну функцию).

Для иллюстрации рассмотрим:

template<class Function>
void functor(Function f)
{ f(0); }

void g(float) {}
void g(double) {}

functor(g);

Нет причин отдавать предпочтение одной версии g по сравнению с другой, и если вы явно не специализируетесь на functor (functor<void(float)>(f) в порядке), вывод аргументов шаблона должен потерпеть неудачу.

Это также верно, если g является шаблоном: http://coliru.stacked-crooked.com/a/8e27a45bbeedd979

person YSC    schedule 06.03.2019