Ленивая оценка по параметру шаблонной функции - PullRequest
2 голосов
/ 12 января 2012

У меня есть класс для ведения журнала, который НЕ ДОЛЖЕН наследовать std :: ostream и имеет оператор <<, определенный для тех же типов, что и стандартный поток вывода, плюс шаблонную версию: </p>

class MyLoggingClass {
[...]
public:
    template<typename T> MyLoggingClass & operator<<( T& data ){ ... }
}

Кроме того, для каждого печатаемого класса в моей программе определена типичная функция, не являющаяся членом:

std::ostream & operator << ( std::ostream & os, const OneOfMyClasses & foo );

Дело в том, что внутри моего регистратора иногда используется стандартный поток вывода, это:

template<typename T>
MyLoggingClass & operator<<( T& data )
{
    [...]
    if( someCondition )
    {
        cout << data;
    }
    [...]
}

Благодаря этому я могу записывать свои классы без явной репликации на каждый из них оператора, не являющегося членом << для MyLoggingClass. Проблема возникает в строке, где я пытаюсь зарегистрировать объект, созданный «на лету»: </p>

MyLoggingClass logger;
logger << OneOfMyClasses(params); // Here I am invoking the constructor of class "OneOfMyClasses"

Дело в том, что вместо вызова конструктора и последующей передачи объекта в качестве параметра оператора << он интерпретирует, что я пытаюсь записать указатель на функцию. </p>

Конечно, некоторые допустимые решения этой проблемы включают:

  • Удаление шаблонного оператора << и расширение MyLoggingClass std :: ostream </li>
  • Удаление шаблонного оператора << и создание множества операторов, не являющихся членами << (MyLoggingClass &, const OneOfMyClasses &) </li>
  • Сохранение объекта для входа во временную переменную, а затем выполнение "logger << temporalObject;" Тем не менее, я хотел бы знать, есть ли способ заставить компилятор оценивать вызов конструктора. Знаете ли вы какой-нибудь обходной путь для этого случая? </li>

Заранее спасибо за ваше время :) 1025 *

1 Ответ

6 голосов
/ 12 января 2012

Я думаю, что проблема заключается в следующем:

template<typename T> MyLoggingClass & operator<<( T& data ){ ... }

data является неконстантной ссылкой, а строка:

logger << OneOfMyClasses(params);

пытается связать временный объект с-константная ссылка.

Изменить на:

template<typename T> MyLoggingClass & operator<<(const T& data ){ ... }
                                               //^^^^^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...