Итерация тензора над размерностью None в тензорном потоке

Как указано в ответе AnT, это, по-видимому, является упущением стандарта и отсутствием правильного синтаксиса для выражения того, что вы хотите сделать. На днях мой коллега столкнулся с этой проблемой и назвал ваш вопрос и его ответ доказательством того, что это невозможно. Ну, мне нравится вызов, и да, это можно сделать ... но его не очень.

Во-первых, важно понимать, что указатель на член в основном является смещением от указателя на структуру [1]. У языка есть оператор смещения, который подозрительно похож на этот, и, что интересно, дает нам выразительность, необходимую для выполнения того, что мы хотим.

Проблема, с которой мы немедленно сталкиваемся, заключается в том, что C ++ запрещает указывать указатели на элементы. Ну, почти ... у нас есть союз, заброшенный нашими рукавами. Как я уже сказал, это некрасиво!

. В конце концов, нам также нужно знать правильный тип указателя, который нужно отличить.

Итак, без дальнейших церемоний, вот код ( проверено на gcc и clang):

template <typename C, typename T, /*auto*/size_t P>
union MemberPointerImpl final {
  template <typename U> struct Helper
    { using Type = U C::*; };
  template <typename U> struct Helper<U&>
    { using Type = U C::*; };

  using MemberPointer = typename Helper<T>::Type;

  MemberPointer o;
  size_t i = P; // we can't do "auto i" - argh!
  static_assert(sizeof(i) == sizeof(o));
};

#define MEMBER_POINTER(C, M) \
  ((MemberPointerImpl<__typeof__(C),          \
      decltype(((__typeof__(C)*)nullptr)->M), \
      __builtin_offsetof(__typeof__(C), M)    \
  >{ }).o)

Сначала посмотрим на макрос MEMBER_POINTER. Он принимает два аргумента. Первая, C - это структура, которая будет базой для указателя-члена. Обертка его в __typeof__ не является строго необходимой, но позволяет передавать либо тип, либо переменную. Второй аргумент M предоставляет выражение тому, членом которого мы хотим указатель.

Макрос MEMBER_POINTER извлекает из этих аргументов две дополнительные части информации и передает их как параметры в MemberPointerImpl шаблон союза. Первая часть - это тип элемента, на который указывает. Это делается путем построения выражения с использованием нулевого указателя, на котором мы используем decltype. Вторая часть - это смещение от базовой структуры к рассматриваемому элементу.

Внутри MemberPointerImpl нам нужно построить тип MemberPointer, который будет тем, что возвращается макросом. Это делается с помощью вспомогательной структуры, которая удаляет ссылки, которые бесполезно возникают, если наш член является элементом массива, что также позволяет поддерживать это. Он также позволяет gcc и clang дать нам хороший полностью расширенный тип в диагностике, если мы назначим возвращаемое значение переменной с несогласованным типом.

Итак, чтобы использовать MEMBER_POINTER, просто измените свой код:

bool MyStruct::* toto = &MyStruct::inner.c;

to:

bool MyStruct::* toto = MEMBER_POINTER(MyStruct, inner.c);

[1] Хорошо, оговорка: это может быть неверно для всех архитектур / компиляторов, поэтому переносимые разработчики кода отвлекают взгляд сейчас!

1
задан Stringer Bell 18 January 2019 в 13:25
поделиться

1 ответ

Если вы действительно хотите это сделать, вы можете использовать tf.map_fn

В противном случае вы можете попытаться напрямую разобраться с исходным тензором (с первым измерением = Нет) и выполнить операции на правильных осях (не нужно зацикливаться)

0
ответ дан abcdaire 18 January 2019 в 13:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: