В образовательных целях я пытаюсь создать std::integer_sequence
и суммировать его элементы в виде пакета параметров.Я ожидал, что это будет просто, и написал код ниже.
Шаг 1: Создан набор операций add () - для правильной обработки однородных целочисленных пакетов параметров.Протестировано с add<0,1,2,3>()
-call и сработало.
Шаг 2: На этом шаге я хотел передать std::integer_sequence
в качестве параметра-шаблона, чтобы суммировать целые числа в последовательности.Не удалось, см. Закомментированный код.
Как передать std::integer_sequence
в качестве параметра шаблона?
Одно сообщение об ошибке состоит в том, что ни один экземпляр общего числа шаблона функции не соответствует вызову.Зачем?Я ожидал, что целочисленная последовательность будет эквивалентна пакету параметров int
.
В другом сообщении об ошибке говорится, что параметр шаблона Args
не является константой.Как это может быть?Я ожидаю, что это будет последующей ошибкой, но я часто видел эту комбинацию ошибок в своих экспериментах.
Я использую компилятор Microsoft VC ++ 2017.
#include <iostream>
#include <utility>
template <typename T>
T add(T first) {
return first;
}
template <typename T, typename ... Args>
T add(T car, Args... cdr) {
return car + add(cdr...);
}
template <int ... Args>
int total() {
return add(Args...);
}
int main(int argc, char** argv)
{
using std::cout;
using std::endl;
int s1 =
total<0, 1, 2, 3>();
std::cout << "s1 = " << s1 << std::endl;
// The following does not compile:
#if 0
int s2 =
total<std::make_integer_sequence<int, 4>>();
std::cout << "s2 = " << s2 << std::endl;
static_assert(s1 == s2, "no match");
#endif
// This should work:
//
{
cout << typeid(std::make_integer_sequence<int, 4>()).name() << endl;;
cout << std::make_integer_sequence<int, 4>().size << endl;;
}
return 0;
}
...Позже, после множества полезных комментариев.Я многому научился и теперь у меня есть следующий рабочий код:
#include <iostream>
#include <utility>
template <typename T>
constexpr T add(T first) {
return first;
}
template <typename T, typename ... Args>
constexpr T add(T car, Args... cdr) {
return car + add(cdr...);
}
template <int ... Args>
constexpr int total() {
return add(Args...);
}
template<int... Args>
constexpr int total(std::integer_sequence<int, Args...>) {
return total<Args...>();
}
int main(int argc, char** argv)
{
using std::cout;
using std::endl;
constexpr int s1 =
total<0, 1, 2, 3>();
std::cout << "s1 = " << s1 << std::endl;
// The following now compiles. Oh, happy day!
#if 1
constexpr int s2 =
total(std::make_integer_sequence<int, 4> {});
std::cout << "s2 = " << s2 << std::endl;
static_assert(s1 == s2, "no match");
#endif
// This should work:
//
{
cout << typeid(std::make_integer_sequence<int, 4>()).name() << endl;;
cout << std::make_integer_sequence<int, 4>().size << endl;;
}
return 0;
}