Re[3]: Опять специализация: результат по типу
От: Павел Кузнецов  
Дата: 19.09.02 11:43
Оценка: 5 (1)
Здравствуйте orangy, Вы писали:

O>Павел, а нельзя ли в каком-нибудь кратком виде описать известные тебе механизмы симуляции частичной специализации с комментариями? Особенно интересны ограничения, i.e. что можно сэмулировать, а что нет...


AFAIR, все известные техники симуляции сводятся к тому, что можно специализировать шаблон класса полностью и использованию вложенных шаблонов для передачи собственно аргументов шаблона (пример можно посмотреть в ответе, предназначенном Gadsky). Основные ограничения, которые, насколько я знаю, принципиально не могут быть преодолены без "настоящей" частичной специализации, следующие:
— дискриминирующие функции, применяющиеся при создании многих метафункций, требуют создания "липовой" переменной, поэтому не работают с неполными типами;
— без "настоящей" частичной специализации еще никому не удавалось (и вряд ли удастся) получить тип T, имея, например, T&;
— существующие метафункции IsConst<T>, IsVolatile<T>, IsReference<T> и т.п. некорректно работают в случае, если T имеет квалификаторы и const и volatile одновременно (например, const volatile int&).

O>Не прошу о статье, хотя хотелось бы конечно, но хоть основные вещи.


Статья уже полностью готова, ждет, пока у админов дойдут руки выложить в соответствующий раздел сервера.

P.S. хорошие вопросы, статья не их затрагивает, может, стоит рассмотреть их более подробно в продолжении?..
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Опять специализация: результат по типу
От: Gadsky Россия  
Дата: 19.09.02 09:43
Оценка:
Пример:

template <typename T> class GetId() {
   int operator() () { return 0; }
}

template <> class GetId()<char> {
   int operator() () { return 1; }
}


template <> class GetId()<vector<class> > {
   int operator() () { return 2; }
}

GetId<int> intId;
GetId<char> charId;
GetId<vector<int> > vectorOfIntId;


После этого intId() == 0, charId() == 1, а вот vectorOfInt() == 0
Подскажите, пожалуйста, как реализовать Subj...
Re: Опять специализация: результат по типу
От: Павел Кузнецов  
Дата: 19.09.02 10:40
Оценка:
Здравствуйте Gadsky, Вы писали:

G>
G>template <typename T> class GetId() {


Синтаксическая ошибка. Продолжаю, считая, что ты хотел написать:
template <typename T> class GetId {


G>
G>   int operator() () { return 0; }
G>}
G>
G>template <> class GetId()<char> {
G>   int operator() () { return 1; }
G>}
G>
G>template <> class GetId()<vector<class> > {


Синтаксическая ошибка: vector<class>. Что ты этим хотел сказать?

G>
G>   int operator() () { return 2; }
G>}


Если ты хотел сказать, что все GetId<vector<...> >::operator() должны возвращать 2, то это называется частичная специализация и пишется так:

template<typename U>
class GetId<std::vector<U> > {
  int operator()() const { return 2; }
};


MSVC++ подобное не поддерживает, но при необходимости можно выкрутиться с помощью симуляции частичной специализации.
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: GUI
От: Gadsky Россия  
Дата: 19.09.02 10:52
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>Синтаксическая ошибка. Продолжаю, считая, что ты хотел написать:

ПК>
ПК>template <typename T> class GetId {


ПК>Если ты хотел сказать, что все GetId<vector<...> >::operator() должны возвращать 2, то это называется частичная специализация и пишется так:


ПК>
ПК>template<typename U>
ПК>class GetId<std::vector<U> > {
ПК>  int operator()() const { return 2; }
ПК>};


ПК>MSVC++ подобное не поддерживает, но при необходимости можно выкрутиться с помощью симуляции частичной специализации.


Да, ошибок я немало понаделал — запятые, опять же.
Очень хотелось бы узнать, как же частичную специализацию эмулировать: можно ссылки, можно здесь.
Re[3]: GUI
От: Павел Кузнецов  
Дата: 19.09.02 11:11
Оценка:
Здравствуйте Gadsky, Вы писали:

G>Да, ошибок я немало понаделал — запятые, опять же.

G>Очень хотелось бы узнать, как же частичную специализацию эмулировать: можно ссылки, можно здесь.

На днях на rsdn должна выйти статья как раз про это. Объяснение использованных техник можно будет найти там. Вкратце для твоего случая так:

#include <iostream>
#include <vector>

template<class T>
class GetId_
{
public:
  int operator()() const { return 0; }
};

template<class T>
class GetId_vector_
{
public:
  int operator()() const { return 2; }
};

template<bool is_vector /*true*/>
struct GetIdTraits
{
  template<class T>
  struct Args
  {
    typedef GetId_vector_<T> Base;
  };
};

template<>
struct GetIdTraits<false> // is not vector<>
{
  template<class T>
  struct Args
  {
    typedef GetId_<T> Base;
  };
};

typedef char   TrueType;
typedef double FalseType;

template<class T>
class IsVector
{
private:
  // реализации статических членов не требуется, достаточно объявления

  // если нужно только для std::vector<T, std::allocator<T> >, то заменить на:
  // template<class T>
  // static TrueType discriminator(const std::vector<T, std::allocator<T> >&);
  template<class T, class A>
  static TrueType discriminator(const std::vector<T, A>&);

  static FalseType discriminator(...);

  static T t;

public:
  enum { value = sizeof(discriminator(t)) == sizeof(TrueType) };
};

template<class T>
class GetId : public GetIdTraits<IsVector<T>::value>::template Args<T>::Base
{
};

template<>
class GetId<int>
{
public:
  int operator()() const { return 1; }
};

GetId<int>               intId;
GetId<char>              charId;
GetId<std::vector<int> > vectorOfIntId;

int main()
{
  std::cout << "intId:         " << intId() << std::endl;
  std::cout << "charId:        " << charId() << std::endl;
  std::cout << "vectorOfIntId: " << vectorOfIntId() << std::endl;
  return 0;
}
<< J 1.0 alpha 5 >>
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[2]: Опять специализация: результат по типу
От: orangy Россия
Дата: 19.09.02 11:20
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>MSVC++ подобное не поддерживает, но при необходимости можно выкрутиться с помощью симуляции частичной специализации.


Павел, а нельзя ли в каком-нибудь кратком виде описать известные тебе механизмы симуляции частичной специализации с комментариями?
Особенно интересны ограничения, i.e. что можно сэмулировать, а что нет...
Не прошу о статье, хотя хотелось бы конечно, но хоть основные вещи. А то я как начинаю копаться в template metaprogramming — крыша едет. Вроде, что написано у других более менее понятно как работает, а вот когда доходит до написать что-то своё — не выходит каменный цветок.
В сети каких-либо более менее внятных туториалов не нашёл...
... << J 1.0 alpha 4 >>
"Develop with pleasure!"
Re[4]: Опять специализация: результат по типу
От: Kaa Украина http://blog.meta.ua/users/kaa/
Дата: 19.09.02 19:03
Оценка:
Здравствуйте Павел Кузнецов, Вы писали:

ПК>P.S. хорошие вопросы, статья не их затрагивает, может, стоит рассмотреть их более подробно в продолжении?..


Крест на пузе... Эээ. В смысле, стоит.
Алексей Кирдин
Re[4]: Спасибо за ответ
От: Gadsky Россия  
Дата: 20.09.02 03:57
Оценка:
Subj.
Павел, а какие источники по metaprogramming
с вагей точки зрения стоит поизучать?
Re[4]: Опять специализация: результат по типу
От: Павел Кузнецов  
Дата: 20.09.02 14:07
Оценка:
ПК>Статья уже полностью готова, ждет, пока у админов дойдут руки выложить в соответствующий раздел сервера.

ПК>P.S. хорошие вопросы, статья не их затрагивает, может, стоит рассмотреть их более подробно в продолжении?..


Похоже, я несколько поторопился с объявлением скорой доступности статьи — прошу прощения. С другой стороны, это даже хорошо: будет возможность добавить часть, рассматривающую затронутые вопросы. Поживем — увидим.
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.