Чтобы протестировать и отобразить результат некоторых функций моей библиотеки, я создаю ряд удобных функций.
Я имею execute
функция, которая похожа:
template <typename R, typename I>
std::string execute( const std::string& func_name, R(*func_ptr)( const I& ), const I& func_input );
Это вызывает функцию, и отобразите результаты и аргументы в отформатированной строке, что я могу отправить к std::cout
.
Проблема состоит в том, что некоторые мои функции не возвращают конвертируемые к строке результаты. Я думал, что мог просто перегрузить глобальное ::operator std::string
с чем-то как:
template <typename T>
operator std::string( const std::vector<T>& v );
Но GCC жалуется:
error: 'operator std::string(const std::vector<T, std::allocator<_CharT> >&)' must be a nonstatic member function
Ну, проблема, конечно, состоит в том, что я не могу добавить членские операторы к std::vector
, и даже для моих классов, я не хочу загрязнять их "для тестирования" операторов преобразования.
Я предполагаю, что могу добавить слой косвенности и использовать функцию вместо оператора преобразования, но это не было бы более эстетическим решением. Я мог также перегрузиться ::operator <<
для std::ostream
и используйте a std::ostringstream
, но это также не самое чистое решение.
Я задался вопросом, является ли глобальный оператор преобразования действительно не сверхзагружаемым, и если так, почему.
Операторы преобразования (операторы приведения) должны быть членами конвертируемого класса, который производит преобразованный тип. Как операторы присваивания, они должны быть функциями-членами, как говорит вам компилятор.
В зависимости от того, сколько усилий вы хотите вложить в отладочную часть, вы можете попробовать использовать метапрограммирование для пересылки вашего метода execute различным фактическим реализациям, предоставляя конкретные для контейнеров, которые будут печатать содержимое.
Почему вы не хотите предоставить operator<<
для ваших типов? Я думаю, что на самом деле это идиоматическое решение. В отличие от других языков, в которых вы используете методы, конвертирующие в строку для получения печатаемых результатов, в C++ идиоматическим способом является предоставление operator<<
, а затем использование stringstreams
(или boost::lexical_cast
или другого подобного решения) для конвертации в строки на основе реализации operator<<
. Существует простой класс здесь для создания string
из элементов, которые переопределяют operator<<
, если вы хотите использовать его в качестве отправной точки.
Мне было интересно, действительно ли глобальный оператор преобразования не перегружаем, и если да, то почему.
Нет, такого нет. Функции преобразования должны быть членами класса. Если бы это было не так, это сделало бы разрешение перегрузки особенно неприятной проблемой для компилятора из-за неоднозначности.
Нет определяемого пользователем глобального оператора преобразования. Вы должны управлять либо целевым типом (в этом случае неявным конструктором с одним параметром является оператор преобразования), либо исходным типом (в этом случае вам необходимо перегрузить оператор-член target ()).
Также можно попробовать XFileDialog . Еще не пробовал, но, похоже, стоит оценить.
-121--2213915- Вы можете сделать переменную (она в любом случае глобальна) явным членом окна
:
window.aVariable = 'default';
и более поздних
if (! ('aVariable' in window)) {
window.aVariable = 'new value';
}
Если вы не хотите или не можете изменить код, тогда я бы предложил прагматичный ansatz и игнорировать жалобы JSLint, так как ваш код будет работать
-121--2823062-Функция преобразования должна быть функцией-членом. Функция не может указывать возвращаемый тип, и список параметров должен быть пустым. Они должны использоваться скудно, и должен быть четкий путь преобразования из одного типа в другой. Иначе они могут привести к неожиданным результатам и загадочным ошибкам.