У меня есть класс потока, совместимый со стандартным по интерфейсу, и я могу в эту функцию передавать как std::cout, так и myNS::myStream.
Теперь, я хочу вывести значение в 16ти-ричном виде. В std::iomanip есть манипулятор hex, есть он и myNS::iomanip, и синтаксически совместим со стандартным. Но я не могу его использовать, не указав его с полным именем NS. Мне нужно перед вызовом printSomething сделать using namespace std::iomanip, или using namespace myNS::iomanip. Но это делать не хочется.
Вариант — настроить поток на вывод hex'ов — не вариант — в функции printSomething я хочу вывести много полей структуры, и все — по-разному.
Есть ли какое-то решение?
Re: Поиск имени в NS параметра шаблона - можно что-то подобн
Здравствуйте, удусекшл, Вы писали:
У>Теперь, я хочу вывести значение в 16ти-ричном виде. В std::iomanip есть манипулятор hex, есть он и myNS::iomanip, и синтаксически совместим со стандартным. У>Есть ли какое-то решение?
Есть некрасивое и простое решение: можно добавить для myNS::myStream::hex манипулятора перегрузку оператора << для ostream класса и тогда можно использовать myNS::iomanip везде, но наверное есть другое, красивое решение.
PS Придумал:
template<class T> auto S_HEX = std::hex;
template<> auto S_HEX<myNS::iomanip> = myNS::iomanip::hex;
template< typename StreamType >
void printSomething( StreamType s, const Something &something)
{
s << S_HEX<StreamType> << something.member;
//...
}
Должно работать, но надо подумать над порядком инициализации глобальных переменных.
Кроме того, может быть на auto можно навесить constexpr и &
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, удусекшл, Вы писали:
У>>Теперь, я хочу вывести значение в 16ти-ричном виде. В std::iomanip есть манипулятор hex, есть он и myNS::iomanip, и синтаксически совместим со стандартным. У>>Есть ли какое-то решение? BFE>Есть некрасивое и простое решение: можно добавить для myNS::myStream::hex манипулятора перегрузку оператора << для ostream класса и тогда можно использовать myNS::iomanip везде, но наверное есть другое, красивое решение.
Ну, в принципе годно, спс
BFE>PS Придумал: BFE>
BFE>template<class T> auto S_HEX = std::hex;
BFE>template<> auto S_HEX<myNS::iomanip> = myNS::iomanip::hex;
BFE>...
BFE>
BFE>Должно работать, но надо подумать над порядком инициализации глобальных переменных. BFE>Кроме того, может быть на auto можно навесить constexpr и &
Спс. А это уже 17ый или еще 14ый?
Re[3]: Поиск имени в NS параметра шаблона - можно что-то подобн
Здравствуйте, удусекшл, Вы писали:
У>Спс. А это уже 17ый или еще 14ый?
ЕМНИП это 14-ый (но я не уверен про поддержку специализации шаблонных переменных).
И каждый день — без права на ошибку...
Re: Поиск имени в NS параметра шаблона - можно что-то подобное придумать?
Здравствуйте, удусекшл, Вы писали:
У>Есть ли какое-то решение?
Ну на С++17 можно сделать в лоб:
template< typename StreamType >
void printSomething( StreamType s, const Something &something)
{
if constexpr (std::is_same_v<StreamType, Type1>)
// Do output with type 1else if constexpr (std::is_same_v<StreamType, Type2>)
// Do output with type 2
}
Re[4]: Поиск имени в NS параметра шаблона - можно что-то подобн
Может я немного недопонял, но если сделать внутри функции printSomething() using namespace std::iomanip и using namespace myNS::iomanip, это будет не cool?
Здравствуйте, удусекшл, Вы писали:
Мне нужно перед вызовом printSomething сделать using namespace std::iomanip, или using namespace myNS::iomanip. Но это делать не хочется.
У>Есть ли какое-то решение?
Re[2]: Поиск имени в NS параметра шаблона - можно что-то подобное придумать?
Здравствуйте, swingus, Вы писали:
S>Может я немного недопонял, но если сделать внутри функции printSomething() using namespace std::iomanip и using namespace myNS::iomanip, это будет не cool?
Если его манипулятор hex — это тоже функция, наподобие std::hex, то все будет работать — на правах двух перегрузок через ADL. А если его hex — это просто объект — экземпляр перечисления, например, то будет конфликт имен.
Ну и второй момент, я бы, все-таки, избегал using директив, даже в области видимости функций. Я бы предпочел using declarations: using std::hex, using std::dec, using myNS::iomanip::hex, etc.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: Поиск имени в NS параметра шаблона - можно что-то подобное придумать?
Ты почитай ниже, там имеет значение dependent or not dependent (так же, как и в обычных шаблонах).
Если бы все всегда вычислялось, как бы могла работать функция, типа такой (пример оттуда же):
template <typename T>
auto get_value(T t) {
if constexpr (std::is_pointer_v<T>)
return *t; // deduces return type to int for T = int*else
return t; // deduces return type to int for T = int
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, _NN_, Вы писали:
_NN>>Note: the discarded statement can't be ill-formed for every possible specialization: _NN>>https://en.cppreference.com/w/cpp/language/if#Constexpr_If
R>Ты почитай ниже, там имеет значение dependent or not dependent (так же, как и в обычных шаблонах).
В курсе. Ок. Я не достаточно точно написал.
В любом случае у enable_if есть преимущество SFINAE .
Здравствуйте, swingus, Вы писали:
S>Может я немного недопонял, но если сделать внутри функции printSomething() using namespace std::iomanip и using namespace myNS::iomanip, это будет не cool?
В этом случае нужно подключать всё хидеры. А смысл шаблона в том, чтобы уйти от конкретных типов, и, в тч, ничего лишнего заранее не инклудить
Re[3]: Поиск имени в NS параметра шаблона - можно что-то под
Здравствуйте, удусекшл, Вы писали:
S>>Может я немного недопонял, но если сделать внутри функции printSomething() using namespace std::iomanip и using namespace myNS::iomanip, это будет не cool?
У>В этом случае нужно подключать всё хидеры. А смысл шаблона в том, чтобы уйти от конкретных типов, и, в тч, ничего лишнего заранее не инклудить
Ну так эта проблема существут в любом из предложенных решений. Вот
Здесь std::hex не является зависимым именем и его объявление должно быть видимо в этой точке.
В то же время, я думаю, не будет большим преступлением сделать в собственном коде предварительные объявления некоторых сущностей, которые жестко зафиксированы в стандарте языка, чтоб не подключать заголовки без необходимости:
В варианте using namespace xxx достаточно форвардно объявить namespace xxx {}.
Здравствуйте, удусекшл, Вы писали:
У>В этом случае нужно подключать всё хидеры. А смысл шаблона в том, чтобы уйти от конкретных типов, и, в тч, ничего лишнего заранее не инклудить