специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 18:42
Оценка:
приветствую!

нужно перегрузить сабжевый оператор для того, чтоб все выводимые строки оборачивались в "\""

пытаюсь сделать такое:
template<typename T, bool ok = std::is_same<T, std::string>::value /*|| std::is_fundamental<T>::value*/>
std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {
    return s << o;
}

на что компилятор мне говорит:

main.cpp:341:94: error: 'std::ostream& std::operator<<(std::ostream&, const T&, typename std::enable_if<ok>::type*)' must take exactly two arguments
std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {


вопрос в том, как побороть?

благодарен!
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 18:58
Оценка:
Здравствуйте, niXman, Вы писали:

X>приветствую!


X>нужно перегрузить сабжевый оператор для того, чтоб все выводимые строки оборачивались в "\""


X>пытаюсь сделать такое:

X>
X>template<typename T, bool ok = std::is_same<T, std::string>::value /*|| std::is_fundamental<T>::value*/>
X>std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {
X>    return s << o;
X>}

X>

X>на что компилятор мне говорит:
X>

X>main.cpp:341:94: error: 'std::ostream& std::operator<<(std::ostream&, const T&, typename std::enable_if<ok>::type*)' must take exactly two arguments
X> std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {


X>вопрос в том, как побороть?


X>благодарен!


похоже компилятор намекает, что operator<< может быть только бинарным
Re: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 19:01
Оценка:
еще один вопрос по оператору вывода, и, чтоб не создавать еще одну мелкую тему, позвольте мне задать его тут

есть такая функция:
std::ostream& quoting(std::ostream &s, const std::string &o) {
   return s << "\"" << o << "\"";
}

при попытке использовать ее так:
cout << "1:" << quoting("2");

получаю в выводе адрес функции, само собой.
есть ли способ, чтоб использование функции оставить таким как показано, но чтоб не адрес выводился, а квотнутая строка?

спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 19:03
Оценка:
Здравствуйте, andyp, Вы писали:

A>похоже компилятор намекает, что operator<< может быть только бинарным

это я понял. выше же написал об этом.

вопрос в том, каким образом специализировать этот оператор?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 19:05
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, andyp, Вы писали:


A>>похоже компилятор намекает, что operator<< может быть только бинарным

X>это я понял. выше же написал об этом.

X>вопрос в том, каким образом специализировать этот оператор?


определи свой класс-враппер EscapedString (ну или еще что-то), хранящий ссылку на std::string и свой operator<< для этого класса. operator<< для std::string уже есть в стандартной библиотеке
Re[4]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 19:09
Оценка:
Здравствуйте, andyp, Вы писали:

A>определи свой класс-враппер EscapedString (ну или еще что-то), хранящий ссылку на std::string и свой operator<< для этого класса. operator<< для std::string уже есть в стандартной библиотеке

так это же весь код придется перелопатить!
я же хотел глобально переопределить.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 19:14
Оценка:
Здравствуйте, niXman, Вы писали:

X>еще один вопрос по оператору вывода, и, чтоб не создавать еще одну мелкую тему, позвольте мне задать его тут


X>есть такая функция:

X>
X>std::ostream& quoting(std::ostream &s, const std::string &o) {
X>   return s << "\"" << o << "\"";
X>}
X>

X>при попытке использовать ее так:
X>
X>cout << "1:" << quoting("2");
X>

X>получаю в выводе адрес функции, само собой.
X>есть ли способ, чтоб использование функции оставить таким как показано, но чтоб не адрес выводился, а квотнутая строка?

X>спасибо.




std::string& quoting(const std::string &o) {
     std::ostringstream s;
     s << "\"" << o << "\"";
     return s.str();   
}

???
Re[3]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 19:23
Оценка:
Здравствуйте, andyp, Вы писали:

A>
A>std::string& quoting(const std::string &o) {
A>     std::ostringstream s;
A>     s << "\"" << o << "\"";
A>     return s.str();   
A>}
A>

A>???
нет. так и я могу)
функция описана выше. ее менять не нужно.
думал, что есть какой-то способ...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 19:26
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, andyp, Вы писали:


A>>определи свой класс-враппер EscapedString (ну или еще что-то), хранящий ссылку на std::string и свой operator<< для этого класса. operator<< для std::string уже есть в стандартной библиотеке

X>так это же весь код придется перелопатить!
X>я же хотел глобально переопределить.

по идее можно свой operator<<(std::ostream&, std::string) определитьв нужном (например, глобальном) namespace
Re: специализация на основании type-traits для operator<<(...)
От: rg45 СССР  
Дата: 20.11.13 20:02
Оценка: 15 (1) +1
Здравствуйте, niXman, Вы писали:

X>нужно перегрузить сабжевый оператор для того, чтоб все выводимые строки оборачивались в "\""

X>пытаюсь сделать такое:
X>
X>template<typename T, bool ok = std::is_same<T, std::string>::value /*|| std::is_fundamental<T>::value*/>
X>std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {
X>    return s << o;
X>}
X>

X>на что компилятор мне говорит:
X>

X>main.cpp:341:94: error: 'std::ostream& std::operator<<(std::ostream&, const T&, typename std::enable_if<ok>::type*)' must take exactly two arguments
X> std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {

X>вопрос в том, как побороть?



Тут сразу два соображения.

1. Если уж применять SFINAE, то лучше уж к результату функции в данном случае:
template<typename T, typename U>
using EnableIfString = typename std::enable_if<std::is_same<T, std::string>::value, U>::type;

template<typename T>
EnableIfString<T, std::ostream&> operator<< (std::ostream& s, const T &o) {
   return s << "'" << o << "'";
}


2. SFINAE здесь нафиг не нужен:
std::ostream& operator<< (std::ostream& s, const std::string &o) {
   using std::operator<<; // Без этого уйдем в бесконечную рекурсию
   return s << "'" << o << "'";
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[2]: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 20:24
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, niXman, Вы писали:


X>>нужно перегрузить сабжевый оператор для того, чтоб все выводимые строки оборачивались в "\""

X>>пытаюсь сделать такое:
X>>
X>>template<typename T, bool ok = std::is_same<T, std::string>::value /*|| std::is_fundamental<T>::value*/>
X>>std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {
X>>    return s << o;
X>>}
X>>

X>>на что компилятор мне говорит:
X>>

X>>main.cpp:341:94: error: 'std::ostream& std::operator<<(std::ostream&, const T&, typename std::enable_if<ok>::type*)' must take exactly two arguments
X>> std::ostream& operator<< (std::ostream& s, const T &o, typename std::enable_if<ok>::type* = 0) {

X>>вопрос в том, как побороть?



R>Тут сразу два соображения.


R>1. Если уж применять SFINAE, то лучше уж к результату функции в данном случае:

R>
R>template<typename T, typename U>
R>using EnableIfString = typename std::enable_if<std::is_same<T, std::string>::value, U>::type;

R>template<typename T>
R>EnableIfString<T, std::ostream&> operator<< (std::ostream& s, const T &o) {
R>   return s << "'" << o << "'";
R>}
R>


R>2. SFINAE здесь нафиг не нужен:

R>
R>std::ostream& operator<< (std::ostream& s, const std::string &o) {
R>   using std::operator<<; // Без этого уйдем в бесконечную рекурсию
R>   return s << "'" << o << "'";
R>}
R>


там еще одна проблема будет —

#include <string>
#include <iostream>


std::ostream& operator<<(std::ostream& s , const std::string& ss)
{
    using std::operator<<;
    s<<'A';
    s<<ss;
    s<<'A';
    return s;
}

int main(){
   std::cout<<"1"<<std::endl;
}


будет использовать operator<< из std. Сработает только вот так std::string("1"), а это приведет к изменению кода во многих местах
Re[3]: специализация на основании type-traits для operator<<(...)
От: rg45 СССР  
Дата: 20.11.13 20:32
Оценка: 15 (1) +1
Здравствуйте, andyp, Вы писали:



A>там еще одна проблема будет —

A> . . .
A>будет использовать operator<< из std. Сработает только вот так std::string("1"), а это приведет к изменению кода во многих местах


Да тоже не проблема:

std::ostream& do_output (std::ostream& s, const std::string &o) {
   using std::operator<<;
   return s << "'" << o << "'";
}

std::ostream& operator<< (std::ostream& s, const std::string &o) { return do_output(s, o); }
std::ostream& operator<< (std::ostream& s, const char* o) { return do_output(s, o); }

int main()
{
   std::cout << std::string("Hello") << std::endl;
   std::cout << "Hello" << std::endl;
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[4]: специализация на основании type-traits для operator<<(...)
От: andyp  
Дата: 20.11.13 20:41
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, andyp, Вы писали:




A>>там еще одна проблема будет —

A>> . . .
A>>будет использовать operator<< из std. Сработает только вот так std::string("1"), а это приведет к изменению кода во многих местах


R>Да тоже не проблема:


R>
R>std::ostream& do_output (std::ostream& s, const std::string &o) {
R>   using std::operator<<;
R>   return s << "'" << o << "'";
R>}

R>std::ostream& operator<< (std::ostream& s, const std::string &o) { return do_output(s, o); }
R>std::ostream& operator<< (std::ostream& s, const char* o) { return do_output(s, o); }

R>int main()
R>{
R>   std::cout << std::string("Hello") << std::endl;
R>   std::cout << "Hello" << std::endl;
R>}
R>


ну да. пост был для галочки, чтобы nixman про вторую перегрузку не забыл
Re[4]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 20.11.13 21:39
Оценка:
Здравствуйте, rg45, Вы писали:

R>[ccode]

R>std::ostream& do_output (std::ostream& s, const std::string &o) {
R> using std::operator<<;
R> return s << "'" << o << "'";
R>}

что-то я не подумал о таком способе.

спасибо, вопрос закрыт.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.11.13 07:06
Оценка:
Здравствуйте, niXman, Вы писали:

X>еще один вопрос по оператору вывода, и, чтоб не создавать еще одну мелкую тему, позвольте мне задать его тут


X>есть такая функция:

X>
X>std::ostream& quoting(std::ostream &s, const std::string &o) {
X>   return s << "\"" << o << "\"";
X>}
X>

X>при попытке использовать ее так:
X>
X>cout << "1:" << quoting("2");
X>

X>получаю в выводе адрес функции, само собой.
X>есть ли способ, чтоб использование функции оставить таким как показано, но чтоб не адрес выводился, а квотнутая строка?

а по этому вопросу есть идеи?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: специализация на основании type-traits для operator<<(...)
От: night beast СССР  
Дата: 21.11.13 07:20
Оценка:
Здравствуйте, niXman, Вы писали:

X>>еще один вопрос по оператору вывода, и, чтоб не создавать еще одну мелкую тему, позвольте мне задать его тут


X>>есть такая функция:

X>>
X>>std::ostream& quoting(std::ostream &s, const std::string &o) {
X>>   return s << "\"" << o << "\"";
X>>}
X>>

X>>при попытке использовать ее так:
X>>
X>>cout << "1:" << quoting("2");
X>>

X>>получаю в выводе адрес функции, само собой.

это странно, потому что я получаю ошибку компиляции при попытке преобразовать "const char *" к "std::ostream"
может ты что-то другое компилируешь?

X>>есть ли способ, чтоб использование функции оставить таким как показано, но чтоб не адрес выводился, а квотнутая строка?


X>а по этому вопросу есть идеи?


можешь сформулировать подробней, чего есть, и чего нужно.
Re[4]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.11.13 07:28
Оценка:
да, ошибочка вышла.

вот функция:
std::ostream& quoting(std::ostream &s, const std::string &o) {
   return s << "\"" << o << "\"";
}


а вот так хотелось бы использовать:
cout << "1:" << quoting(cout, "2");
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[5]: специализация на основании type-traits для operator<<(...)
От: night beast СССР  
Дата: 21.11.13 07:36
Оценка:
Здравствуйте, niXman, Вы писали:

X>а вот так хотелось бы использовать:

X>
X>cout << "1:" << quoting(cout, "2");
X>


а что должно выводиться? сейчас печатается адрес std::cout, а нужно?
Re[6]: специализация на основании type-traits для operator<<(...)
От: rg45 СССР  
Дата: 21.11.13 08:52
Оценка: 1 (1)
Здравствуйте, night beast, Вы писали:

X>>а вот так хотелось бы использовать:

X>>
X>>cout << "1:" << quoting(cout, "2");
X>>

NB>а что должно выводиться? сейчас печатается адрес std::cout, а нужно?


Ну при включенной телепатии догадаться можно:

#include <iostream>
#include <string>

template <typename T>
class OutputDecorator
{
public:

   OutputDecorator(const T& object) : m_object(&object) { }

   void operator()(std::ostream& output) const { output << '"' << *m_object << '"'; }

private:
   const T* m_object;
};

template <typename T>
std::ostream& operator << (std::ostream& output, const OutputDecorator<T>& decorator)
{
   decorator(output);
   return output;
}

template <typename T>
OutputDecorator<T> make_decorator(const T& object) { return OutputDecorator<T>(object); }

int main()
{
   std::cout << make_decorator("Hello") << std::endl; // Output: "Hello" (quoted)
}
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[6]: специализация на основании type-traits для operator<<(...)
От: niXman Ниоткуда https://github.com/niXman
Дата: 21.11.13 09:42
Оценка:
Здравствуйте, night beast, Вы писали:

NB>а что должно выводиться? сейчас печатается адрес std::cout, а нужно?

туплю жестко %)

должен выводиться второй аргумент функции, обернутый в двойные кавычки.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.