Следующий код выдает огромный список ошибок компилятора:
/// Uses template recursion to bind all args
template<std::size_t N, typename... Args> class Binder
{
public:
Binder(Sqlite3StatementBase &s, std::tuple<Args...> &tup)
{
Binder<N - 1, Args...> b(s, tup);
s.bind(N + 1, std::get<N, Args...>(tup)); // Line 182
}
};
/// Specialization of Binder to end recursion at 0
template<typename... Args> class Binder<0, Args...>
{
public:
Binder(Sqlite3StatementBase &s, std::tuple<Args...> &tup)
{
s.bind(1, std::get<0, Args...>(tup));
}
};
Первая партия ошибок состоит из:
In file included from /usr/include/c++/6/bits/unique_ptr.h:37:0,
from /usr/include/c++/6/condition_variable:43,
from /home/tony/htpc/Dev/logi/src/db/logi-db.h:22,
from /home/tony/htpc/Dev/logi/src/db/logi-sqlite.h:26,
from /home/tony/htpc/Dev/logi/src/db/logi-sqlite.cpp:24:
/usr/include/c++/6/tuple: In instantiation of ‘class std::tuple_element<1ul, std::tuple<unsigned int> >’:
/usr/include/c++/6/tuple:1228:12: recursively required from ‘class std::tuple_element<2ul, std::tuple<unsigned int, unsigned int> >’
/usr/include/c++/6/tuple:1228:12: required from ‘class std::tuple_element<3ul, std::tuple<unsigned int, unsigned int, unsigned int> >’
/usr/include/c++/6/utility:106:69: required by substitution of ‘template<long unsigned int __i, class _Tp> using __tuple_element_t = typename std::tuple_element::type [with long unsigned int __i = 3ul; _Tp = std::tuple<unsigned int, unsigned int, unsigned int>]’
/usr/include/c++/6/tuple:1270:5: required by substitution of ‘template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_Elements ...> >&& std::get(std::tuple<_Elements ...>&&) [with long unsigned int __i = 3ul; _Elements = {unsigned int, unsigned int, unsigned int}]’
/home/tony/htpc/Dev/logi/src/db/logi-sqlite.h:182:47: required from ‘logi::Sqlite3Database::Binder<N, Args>::Binder(logi::Sqlite3Database::Sqlite3StatementBase&, std::tuple<_Elements ...>&) [with long unsigned int N = 3ul; Args = {unsigned int, unsigned int, unsigned int}]’
/home/tony/htpc/Dev/logi/src/db/logi-sqlite.h:238:71: required from ‘void logi::Sqlite3Database::Sqlite3Statement<Args>::prepare_row(logi::Sqlite3Database::Sqlite3Statement<Args>::Tup&) [with Args = {unsigned int, unsigned int, unsigned int}; logi::Sqlite3Database::Sqlite3Statement<Args>::Tup = std::tuple<unsigned int, unsigned int, unsigned int>]’
/home/tony/htpc/Dev/logi/src/db/logi-sqlite.h:231:28: required from ‘void logi::Sqlite3Database::Sqlite3Statement<Args>::execute(typename logi::Sqlite3Database::Sqlite3Statement<Args>::Parent::ArgsVector&) [with Args = {unsigned int, unsigned int, unsigned int}; typename logi::Sqlite3Database::Sqlite3Statement<Args>::Parent::ArgsVector = std::vector<std::tuple<unsigned int, unsigned int, unsigned int>, std::allocator<std::tuple<unsigned int, unsigned int, unsigned int> > >]’
/home/tony/htpc/Dev/logi/src/db/logi-sqlite.cpp:354:1: required from here
/usr/include/c++/6/tuple:1228:12: error: invalid use of incomplete type ‘class std::tuple_element<0ul, std::tuple<> >’
Таким образом, кажется, что вызов std::get
заставляет другие части системных библиотек (не связанные напрямую с std::get
или std::tuple
) рекурсивно сводить Args... к нулю, и это происходит независимо от моей рекурсии числового параметра шаблона N. Есть ли что-то, что я могу исправить в своем коде, не меняя фундаментально свой подход, или просто невозможно использовать std::get
в контексте, где параметры шаблона кортежа являются вариативными?
std::index_sequence
и достойный вызов...
. Да, это инструмент C++14, но нетрудно найти/написать его реализацию для C++11. - person Nicol Bolas   schedule 23.07.2017get<3>
для кортежа с тремя элементами - конечно, это не компилируется. Три элемента извлекаются сget<0>
поget<2>
. У вас старая добрая ошибка с ошибкой. - person Igor Tandetnik   schedule 24.07.2017index_sequence
поможет, не используя также выражение сворачивания пакета; возможно, это то, что вы имели в виду под «достойным...
вызовом»? Проблема в том, что последнее является функцией С++ 17. Это не проблема для меня, но может быть для людей, которые хотят создавать мой код на консервативных LTS/стабильных дистрибутивах Linux. - person realh   schedule 24.07.2017...
не является функцией C++17. Это функция С++ 11. Использование...
для выражений сворачивания — это функция C++17, но вы можете используйте...
в множестве других способов в C++11. - person Nicol Bolas   schedule 24.07.2017