Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.12.2010, 23:31   #1
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию шаблонные функции, как помочь компилятору выбрать определенную.

в общем такая ситуация:
Код:
class Stream
{
    template<class T> Stream& operator<<(T& o)
    {
        Write(&o,sizeof(o));
        return *this;
    }
    template<class T> Stream& operator<<(T& o)
    {
        o.SaveToStream(*this);
        return *this;
    }
};
как можно компилятору подсказать чтоб он сначало пытался выполнить(скомпилировать) второй(ну можно их порядок сменить, не суть) оператор, и лишь в случае неудачи брал первый?

или никак?

ну или хотя бы, можно компилю сказать что объекты произвольные от опред класса надо обрабатывать иначе?

ЗЫ:кстати маленький вопрос, это нормальное организация оператора или можно void ставить как тип возврата?(в принципе думаю что можно, ведь будет Stream<<T, а не Stream=Stream<<T, но хочу узнать мнение опытных)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 05.12.2010 в 23:52.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.12.2010, 23:43   #2
Гром
Старожил
 
Аватар для Гром
 
Регистрация: 21.03.2009
Сообщений: 2,193
По умолчанию

Сигнатуры у функций полностью идентичны, поэтому такой код будет считаться ошибкой. Если уж так хочется выбирать из двух вариантов, то либо делайте функции с разной сигнатурой, либо логику выбора засовывайте внутрь тела функции. Хотя я вообще не уверен в безопасности и предсказуемости такого подхода.
Цитата:
кстати маленький вопрос, это нормальное организация оператора или можно void ставить как тип возврата?
Лучше оставить так как есть, потому что с void'ом у вас не получится записать так:
Код:
class X;
class Y;
X x;
Y y;
Stream stream;
stream << x << y;
Простые и красивые программы - коды программ + учебник C++
Создание игры - взгляд изнутри - сайт проекта
Тема на форуме, посвященная ему же
Гром вне форума Ответить с цитированием
Старый 05.12.2010, 23:51   #3
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
либо логику выбора засовывайте внутрь тела функции.
как?
мне нужно знать будет на этапе компиляции, есть ли у объекта o метод SaveToStream...

у меня есть лишь один вариант, он наверно верный.
Код:
class Stream
{
    template<class T> Stream& operator<<(T& o)
    {
        Write(&o,sizeof(o));
        return *this;
    }
};

class String
{
    unsigned int SaveToStream(Stream& s)
    {
        //записываем данные и возвращаем обьем  записанного.
    }
};

Stream& operator<<(Stream& s,String& S)
{
    S.SaveToStream(s);
}
так проканает или не?(проверить просто пока не могу, но вопрос хочу выяснить)
Цитата:
Лучше оставить так как есть, потому что с void'ом у вас не получится записать так:
да, вы правы, этот момент важный, спасибо
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.12.2010, 23:56   #4
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

Такое возможно. За примером можно сходить к саттеру. у него есть глава о требовании наличия ф-ии члена у класса. Это свойство класса определяется на этапе компиляции.
_Ч_ вне форума Ответить с цитированием
Старый 05.12.2010, 23:58   #5
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

эммм...к кому сходить?

я понимаю что в итоге сведется похоже к #if #else #endif, но какое условие?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.12.2010, 00:04   #6
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

нет. макросов там не будет. У Саттера в Решения сложных задач есть правильная глава. Она так и называется: Требования наличия функций-членов.
_Ч_ вне форума Ответить с цитированием
Старый 06.12.2010, 00:12   #7
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

я может чего то не понимаю, но почему нельзя специадизировать шаблон? на объект, у которого есть метод savetostream вызывать соответствующуу функцию, на все другие - write
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 06.12.2010, 00:13   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

и мне для каждого класса писать специализацию?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 06.12.2010, 00:20   #9
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

Я вот по памяти накидал один из возможных вариантов. не компилил это да и не доделанный он. Тут главное идею уловить.
Код:
class Stream
{
  template <bool> struct BoolToType {}
  typedef BoolToType<true> TrueType;
  typedef BoolToType<false> FalseType;

  template <typename T>
  struct SaveToStreamDetector
  {
    static const bool HasSaveToStreamMethod = false;
  };

public:
  template<typename T>
  Stream& operator << (const T& o) const
  {
    Serialize(o, BoolToType<SaveToStreamDetector<T>::HasSaveToStreamMethod>());
  }

private:
  template<typename T>
  Stream& Serialize(const T& o, FalseType) const
  {
    Write(&o,sizeof(o));
    return *this;
  }

  template<typename T>
  Stream& Serialize(const T& o, TrueType) const
  {
    o.SaveToStream(*this);
    return *this;
  }
};
Тут остатется лишь реализовать SaveToStreamDetector<T>, который бы для классов, у которых есть требуемый метод имел бы в качестве значения HasSaveToStreamMethod - true, для остальных - false.
О том, как это продетектить в компайлтайме я уже сказал где можно посмотреть. Возможны и другие реализации. это лишь одна из. В бусте также есть классы, которые определяют свойства других классов. Возможно там уже есть готовый детектор.
_Ч_ вне форума Ответить с цитированием
Старый 06.12.2010, 00:27   #10
_Ч_
Форумчанин
 
Регистрация: 07.01.2010
Сообщений: 141
По умолчанию

вообще в вашем случае стоит пойти немного другим путем. сделать так, как сделано в стл. а именно. там есть std:stream, у которого есть метод write или похожая. еще есть стандартная шаблонная ф-ия std:stream <<, которая реализована по умолчанию для всех плоских типов. но если вы пишите класс и хотите чтобы он записывался в стрим стандартным синтаксисом, то вы реализуете свою нешаблонную ф-ию operator <<, которая в качестве аргумента кроме стрима принимает именно ваш класс.
_Ч_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Шаблонные функции в классе Impuls1989 Общие вопросы C/C++ 5 20.09.2010 09:04
Почему нельзя разбивать на отдельные файлы шаблонные функции и классы? lordius Visual C++ 22 08.07.2010 09:49
Как удалить определенную страницу? Мультипликатор Microsoft Office Word 1 28.06.2010 17:39
шаблонные строковые функции MrKarapuz Общие вопросы C/C++ 7 09.11.2009 15:07
Как напечатать определенную страницу k1r1ch Microsoft Office Excel 14 10.07.2009 18:29