Это ошибка компилятора или ошибка программиста? - PullRequest
1 голос
/ 23 марта 2012

Я играю с кортежами в виде списков времени компиляции. В Как я могу иметь несколько пакетов параметров в шаблоне с переменным числом аргументов? Я ответил себе с помощью некоторого кода, который работает как в GCC, так и в Clang, но Clang не будет компилироваться теперь, когда я добавил (что я считаю) идеальным пересылка. Он жалуется, что As... и as... имеют разную длину в std::forward<As>(as).... Как это может быть правдой, когда As... является типом as...? Это As&&... as в параметрах.

#include <iostream>
#include <tuple>

template < typename ... >
struct two_impl {};

// Base case
template < typename F,
           typename ...Bs >
struct two_impl < F, std::tuple <>, std::tuple< Bs... > >  {
  void operator()(F&& f, Bs&&... bs) {
    f(std::forward<Bs>(bs)...);
  }
};

// Recursive case
template < typename F,
           typename A,
           typename ...As,
           typename ...Bs >
struct two_impl < F, std::tuple< A, As... >, std::tuple< Bs...> >  {
  void operator()(F&& f, A&& a, As&&... as, Bs&&... bs) {
    auto impl = two_impl < F, std::tuple < As&&... >, std::tuple < Bs&&..., A&& > >();
    impl(std::forward<F>(f), std::forward<As>(as)..., std::forward<Bs>(bs)..., std::forward<A>(a));
  }
};

template < typename F, typename ...Ts >
void two(F&& f, Ts&& ...ts) {
  auto impl = two_impl< F, std::tuple < Ts... >, std::tuple <> >();
  impl(std::forward<F>(f), std::forward<Ts>(ts)...);
}

struct Test {
  void operator()(int i, float f, double d) {
    std::cout << i << std::endl << f << std::endl << d << std::endl;
  }
};

int main () {
  two(Test(), 1, 1.5f, 2.1);
}

Компиляция с clang -lstdc++ -std=c++0x multiple_parameter_packs.cpp

clang -lstdc++ -std=c++0x multiple_parameter_packs.cpp 
multiple_parameter_packs.cpp:24:50: error: pack expansion contains parameter packs 'As' and 'as' that have different
      lengths (1 vs. 2)
    impl(std::forward<F>(f), std::forward<As>(as)..., std::forward<Bs>(bs)..., std::forward<A>(a));
                                          ~~  ~~ ^
multiple_parameter_packs.cpp:24:5: note: in instantiation of member function 'two_impl<Test, std::tuple<float &&,
      double &&>, std::tuple<int &&> >::operator()' requested here
    impl(std::forward<F>(f), std::forward<As>(as)..., std::forward<Bs>(bs)..., std::forward<A>(a));
    ^
multiple_parameter_packs.cpp:31:3: note: in instantiation of member function 'two_impl<Test, std::tuple<int, float,
      double>, std::tuple<> >::operator()' requested here
  impl(std::forward<F>(f), std::forward<Ts>(ts)...);
  ^
multiple_parameter_packs.cpp:41:3: note: in instantiation of function template specialization
      'two<Test, int, float, double>' requested here
  two(Test(), 1, 1.5f, 2.1);
  ^
1 error generated.

Compilation exited abnormally with code 1 at Fri Mar 23 14:25:14

Ответы [ 2 ]

3 голосов
/ 24 марта 2012

Это похоже на ошибку в старой версии Clang. Код прекрасно работает со стволом Clang, либо с libstdc ++, либо с libc ++.

$ clang++ multiple_parameter_packs.cpp -std=c++11 -stdlib=libc++
$ ./a.out
1
1.5
2.1
1 голос
/ 23 марта 2012

Не думаю, что это:

void operator()(F&& f, A&& a, As&&... as, Bs&&... bs)

вполне возможно.

Пакет параметров должен быть последним аргументом, а за As&&... as следует следующий пакет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...