Вывод количества аргументов в пакете параметров

В C++ я пытаюсь выяснить, как можно определить размер пакета параметров для функции и, кроме того, как можно определить количество параметров определенного типа (например, целых чисел).

template<int N, int N_ints, typename... Ts> 
void foo(Ts... ts){ 
   ...
}

Чтобы я мог назвать это так


foo(1,2,'3')

и это было бы то же самое, что


foo<3,2>(1,2,'3') 

Я даже не смог заставить работать основную проблему, т.е.


template<int N, class... Ts>
std::array<int, N> foo(Ts... ts)
{

    constexpr int n = sizeof...(ts);
    std::array<int, n> out; 
    return out;
}


int main()
{
    auto a = foo(1, 2, 3, '4', 5);
    return 0;
}

терпит неудачу, потому что не может сделать вывод N.

Как вы думаете, почему вам нужен N в списке параметров шаблона? Я имею в виду, что вы уже знаете, что это sizeof...(ts) нет необходимости иметь его в списке

463035818_is_not_an_ai 08.07.2024 20:30

количество intспереди тоже можно посчитать. Нет необходимости иметь его как свободный параметр.

463035818_is_not_an_ai 08.07.2024 20:31

Возможно, подойдет конечный возвращаемый тип, как в template<typename... Ts> auto foo(Ts... ts) -> std::array<int, sizeof...(ts)> { ... }?

Some programmer dude 08.07.2024 20:31

Заголовок не соответствует телу вопроса. Вы знаете размер пакета параметров.

3CxEZiVlQ 08.07.2024 20:31

И в зависимости от используемого вами стандарта C++, возможно, полный вывод возвращаемого типа также может сработать: template<typename... Ts> auto foo(Ts... ts) { return std::array<int, sizeof...(ts)>(); }?

Some programmer dude 08.07.2024 20:32
template<class... Ts> std::array<int, sizeof...(Ts)> foo(Ts... ts) работает на всех C++ начиная с 11.
3CxEZiVlQ 08.07.2024 20:34

Я пытался дать ответ, но, как и другие, я не совсем понимаю, в чем путаница. Вы говорите, что не можете сделать вывод N, но в то же время вы делаете вывод с помощью constexpr int n = sizeof...(ts);

463035818_is_not_an_ai 08.07.2024 20:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
7
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы слишком усложняете задачу, добавляя степени свободы, которых на самом деле нет. Информация о размере пачки и количестве вхождений int в пачке уже есть в пачке.

#include <iostream>

template <typename T,typename... Ts>
struct count {
    static const unsigned value = (std::is_same_v<T,Ts> + ...);
};

template<typename... Ts> 
void foo(Ts... ts){ 
    std::cout << "num params : " << sizeof ...(Ts) << "\n";
    std::cout << "num ints : " << count<int,Ts...>::value << "\n";
}

int main() {
    foo(1,2,3.0);
}

Я не был уверен, хотите ли вы посчитать все вхождения int в пакете или только ведущие. Я выбрал первое. Пуристы могут утверждать, что static_cast<bool> было бы более понятно, но я думаю, что здесь можно обойтись неявным преобразованием.


Если по какой-то причине вам нужно использовать аргументы шаблона, как в вашем примере, вы все равно можете это сделать:

template<typename... Ts> 
auto foo(Ts... ts){ 
    return foo_impl<sizeof ...(Ts),count<int,Ts...>::value>(ts...);
}

Спасибо! Я все еще изучаю C++, так что это очень полезно. Я могу использовать то, что вы предложили, чтобы мой случай с std::array работал godbolt.org/z/77WvbqzPc.

Varchas Gopalaswamy 09.07.2024 15:06

(извините за спам, но я не смог отредактировать свой предыдущий комментарий). Однако я не могу заставить работать немного более сложный случай, и он выдает разные ошибки с GCC и clang! Есть идеи? gcc: godbolt.org/z/o7nW7h7qr clang: godbolt.org/z/58oddnxd1

Varchas Gopalaswamy 09.07.2024 15:13

@VarchasGopalaswamy {1,3} не имеет типа, который можно было бы вывести. И я тоже не понимаю, чего вы хотите, чтобы произошло. Сообщение об ошибке Gccs несколько сбивает с толку, но clang вполне уместен.

463035818_is_not_an_ai 09.07.2024 15:18

Я пытаюсь посмотреть, смогу ли я эмулировать синтаксис нарезки массива FORTRAN с помощью C++. В идеале можно было бы сделать что-то вроде a(1, 2, 1:5:2), чтобы взять соответствующие фрагменты, но я предполагаю, что это невозможно, поскольку символ : не является тем, что нам разрешено перегружать в любом контексте. Я надеялся, что вместо этого можно будет сделать a(1, 2, {1,5,2}), поскольку это красиво и лаконично, но я столкнулся с этой проблемой вывода шаблонов.

Varchas Gopalaswamy 09.07.2024 15:48

Я знаю, что могу сделать a(1, 2, std::array{1,5,2}), и, кажется, это работает (см. godbolt.org/z/ETTn8x761), но было бы здорово, если бы мне не приходилось писать std::array везде... В любом случае, я ценю помощь, поэтому далеко, и я приму ответ

Varchas Gopalaswamy 09.07.2024 15:48

@VarchasGopalaswamy проблема, с которой вы столкнулись сейчас, совершенно не связана с вопросом здесь. Вы можете открыть дополнительный вопрос

463035818_is_not_an_ai 09.07.2024 15:49

Другие вопросы по теме