#c #operator-overloading
#c #оператор-перегрузка
Вопрос:
У меня есть заголовочный файл, который выглядит следующим образом:
#pragma once
//C Output Streams
#include <iostream>
namespace microtask
{
namespace log
{
/**
* Severity level.
*/
enum severity
{
debug,
info,
warning,
error,
critical
};
/**
* Output the severity level.
*/
std::ostreamamp; operator<<(std::ostreamamp; out, const severityamp; level);
}
}
и исходный файл, который выглядит следующим образом:
//Definitions
#include "severity.hpp"
//Namespaces
using namespace std;
using namespace microtask::log;
std::ostreamamp; operator<<(std::ostreamamp; out, const severityamp; level)
{
switch(level)
{
case debug:
out << "debug";
break;
case info:
out << "info";
break;
case warning:
out << "warning";
break;
case error:
out << "error";
break;
case critical:
out << "critical";
break;
default:
out << "unknown";
break;
}
return out;
}
что я пытаюсь скомпилировать в динамическую библиотеку. К сожалению, связывание завершается ошибкой с этим сообщением об ошибке:
undefined reference to `microtask::log::operator<<(std::basic_ostream<char, std::char_traits<char> >amp;, microtask::log::severity constamp;)'
Что я делаю не так? Я проверил другие stackoverflow.com вопросы, которые казались похожими, но, насколько я могу судить, у меня правильный формат для перегрузки оператора.
Ответ №1:
В вашем файле .cpp не указывайте using
, а вместо этого объявите правильное пространство имен:
namespace microtask
{
namespace log
{
::std::ostream amp; operator<<(::std::ostreamamp; out, const severityamp; level)
{
// ...
}
}
}
На самом деле, не говорите using
случайно вообще, если вы можете помочь этому. На мой взгляд, он должен быть зарезервирован для явного отображения базового элемента и запросов ADL.
Комментарии:
1. Что ж, это работает. Теперь, чтобы я снова не повторил ту же ошибку, почему это не работало раньше? (Я приму ваш ответ, как только истечет тайм-аут).
2. Вы определяли
::operator<<
, а неmicrotask::log::operator<<
. Это просто отдельная функция, и та, которая вам нужна, все еще отсутствует. Постоянное решение, за которое будут благодарны даже ваши внуки, — никогда не использоватьusing
🙂3. ах, я понимаю, ну, это имеет смысл, я думаю. Idk, это просто сбило меня с толку, потому что я привык объявлять реализации для подобных методов класса.
4. @root.ctrlc Я считаю, что причина, по которой ваша версия не работает, заключается в том, что ваше определение operator<< в .cpp реализует ::operator<<(out, серьезность), но не microtask::log::operator<<(out, серьезность)
5.
using
предназначен, ну, для использования. Это не влияет на определение.