Могу ли я использовать один параметр шаблона variadic при создании нового? - PullRequest
3 голосов
/ 23 марта 2012

Я пишу lifter, который должен поднять переменную функцию arity в некоторые std :: vectors, которые напоминают таблицу SQL с индексом. Я хочу применить параметр f к каждому набору элементов, имеющих одинаковый идентификатор во всех векторах. У меня возникла проблема с выводом шаблона, и я его здесь разобрал (за исключением логики итератора). Я написал то, что я считаю разумным рекурсивным случаем, но дедукция шаблона считает его нежизнеспособным.

// Simple container type
template <typename T>
struct A {
  T x;
  T y;
  T z;
};

// Wrapper type to differentiate an extracted value from a container
// in template deduction
template <typename T>
struct B {
  T value;
};

// Base case. All A<Ts> have been extracted to B<Ts>.
template <typename F, typename... Ts>
void lift (F f, B<Ts> ...bs) {
  // Call f with extracted values
  f(bs.value...);
}

// Recursive case
template <typename F, typename T, typename... Ts, typename Us>
void lift (F f, A<T> a, A<Ts> ...as, B<Us> ...bs) {
  // Copy a value from the beheaded container A<T>.
  B<T> b = {a.x};
  // Append this B<T> to args and continue beheading A<Ts>.
  lift(f, as..., bs..., b);
}

// Test function
template <typename... Ts>
struct Test {
  void operator () (Ts...) {}
};

int main () {

  B<int> b = {1};
  // No errors for the base case
  lift(Test<>());
  lift(Test<int, int>(), b, b);

  // error: no matching function for call to 'lift'
  // The notes refer to the recursive case
  A<int> a = {1,0,0};
  lift(Test<int>(), a); // note: requires at least 3 arguments, but 2 were provided
  lift(Test<int>(), a, a); // note: requires 2 arguments, but 3 were provided
  lift(Test<int>(), a, a, b); // note: requires 2 arguments, but 4 were provided
}

Что не так с этим кодом?

Игнорирование того, что здесь все передается по значению для удобства чтения и записи. Почему эта компиляция не нужна?

1 Ответ

1 голос
/ 23 марта 2012

Почему бы просто не извлечь значения A и B напрямую?

template <typename T>
T extractValue(A<T> a)
{
    return a.x;
}
template <typename T>
T extractValue(B<T> b)
{
    return b.value;
}

template <typename F, typename... T>
void lift (F f, T... values) {
    f(extractValue(values)...);
}

Кроме того, ваши последние 2 тестовых примера не могут быть скомпилированы, поскольку число аргументов неверно.

lift(Test<int,int>(), a, a);
lift(Test<int,int,int>(), a, a, b);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...