C ++ еще более обобщенный оператор шаблонизаторов - PullRequest
1 голос
/ 26 сентября 2011

Так что я только что узнал (спасибо, ребята) о decltype. Теперь я могу написать действительно хорошие векторные шаблоны, которые на самом деле превосходят valarrays (!):

template <typename T, typename U>
vector<decltype(T()*U())> operator*(const vector<T>& A, const vector<U>& B){
  vector<decltype(T()*U())> C = vector<decltype(T()*U())>(A.size());
  typename vector<T>::const_iterator a = A.begin();
  typename vector<U>::const_iterator b = B.begin();
  typename vector<decltype(T()*U())>::iterator c = C.begin();
  while (a!=A.end()){
    *c = (*a) + (*b);
    a++; b++; c++;
  }
  return C;
}  

Можно ли сделать этот тип шаблонов еще более "мета" в том смысле, что мы позволяем самому оператору ("*") быть параметром шаблона? То есть иметь одно единственное определение шаблона, которое работает для *, +,% и т. д., где соответствующий оператор op используется в * c = (* a) op (* b)?

Держу пари, что это не так, но было бы неплохо!

Ответы [ 2 ]

2 голосов
/ 26 сентября 2011

Как вы и ожидали, этот ответ «нет».:)

Однако вы можете использовать препроцессор для генерации таких функций:

#define OPERATOR_BLOB(optype) \
    vector<…> operator optype (…) { … }

OPERATOR_BLOB(*)
OPERATOR_BLOB(+)
…
0 голосов
/ 26 сентября 2011

Используйте std::declval<T&&>() вместо T(), у него может не быть конструктора по умолчанию (поскольку std :: vector не требует конструктора по умолчанию, только конструктор копирования).Кроме того, будьте очень уверенными в отношении правильности и пересылки ссылок типа и ссылки и значения, классы могут реализовывать вещи по-разному для значений, ссылок, ссылок на константы, ссылок на значения.Протестируйте его с несколькими классами.

Также учтите, что извлечение возвращаемого типа может не работать для составных операторов присваивания в GCC из-за невыполненной функции.

И да, я решил это с параметризованныммакросы в моем классе оболочки указателя: http://frigocoder.dyndns.org/code/Frigo/Lang/ref

Например

#define PROXY_BINARY_OPERATOR(_) \
    template <class Arg> \
    decltype(std::declval<T&&>() _ std::declval<Arg&&>()) operator _ (Arg&& arg) \
    { \
        return std::forward<T>(get()) _ std::forward<Arg>(arg); \
    } \
    template <class Arg> \
    decltype(std::declval<const T&&>() _ std::declval<Arg&&>()) operator _ (Arg&& arg) const \
    { \
        return std::forward<T>(get()) _ std::forward<Arg>(arg); \
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...