Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
1

Шаблон класса с любым количеством аргументов

14.05.2019, 19:48. Просмотров 1666. Ответов 17
Метки нет (Все метки)

В статье: https://en.cppreference.com/w/... meter_pack
есть такой пример:
C++
1
2
3
4
5
template<class ... Types> struct Tuple {};
Tuple<> t0;           // Types contains no arguments
Tuple<int> t1;        // Types contains one argument: int
Tuple<int, float> t2; // Types contains two arguments: int and float
Tuple<0> error;       // error: 0 is not a type
Но при попытке повторить вылезает куча ошибок
C++
1
2
3
4
5
6
7
8
9
template<class... Args> struct ThreadArgsContainer {};
 
template< typename F, typename... Args >
inline void st::Thread::set(F  lpStartAddress, Args&&... args)
{
    handle = CreateThread(NULL, 0, lpStartAddress, &ThreadArgsContainer<args>, CREATE_SUSPENDED, (LPDWORD)&id);
    pause_b = true;
    cout << handle << ":" << id << endl;
}
Ошибки:
class: отсутствует имя тега
недопустимый тип для параметра шаблона "<unnamed-tag>", не являющегося типом
синтаксическая ошибка: отсутствие "," перед "..."
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.05.2019, 19:48
Ответы с готовыми решениями:

Шаблон функции с переменным количеством аргументов
Добрый вечер, мне необходимо при помощи шаблона функции реализовать поиск минимального числа(тип...

Шаблоны функций, Ошибка: для использования класса шаблон требуется список аргументов шаблон
Есть у меня 3 структуры Трамвай , Троллейбус , Автобус. Для автобуса определены функции (работают)...

Шаблон класса, передача аргументов
Есть шаблон класса, аргументы для создания класса константные itk::Vector &lt;float,ch &gt; шаблон...

Отсутствует список аргументов для шаблон класса std::vector
Есть функция: LoadFBX(std::vector* pOutVertexVector); на загрузку модели формата FBX в DX. На...

17
Mental handicap
1242 / 620 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
14.05.2019, 20:00 2
Цитата Сообщение от Timon32 Посмотреть сообщение
C++
1
CreateThread(NULL, 0, lpStartAddress, &ThreadArgsContainer<args>, CREATE_SUSPENDED, (LPDWORD)&id);

Это оптимистично надеятся что Сишный интерфейс сможет в шаблоны из С++.
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 20:03  [ТС] 3
Попробовал закомментировать строку
C++
1
CreateThread(NULL, 0, lpStartAddress, &ThreadArgsContainer<args>, CREATE_SUSPENDED, (LPDWORD)&id);
, ошибки остались.
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
14.05.2019, 20:04 4
Попробуйте упаковку-разупаковку.
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 20:07  [ТС] 5
Бесполезно студия ругается на
C++
1
template<class... Args> struct ThreadArgsContainer {};
и всё.
0
Mental handicap
1242 / 620 / 171
Регистрация: 24.11.2015
Сообщений: 2,426
14.05.2019, 20:26 6
Цитата Сообщение от Timon32 Посмотреть сообщение
ошибки остались.
Какие? Где?
Откуда мы знаем что вы сделали? Где код?
0
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
14.05.2019, 20:52 7
Цитата Сообщение от Azazel-San Посмотреть сообщение
Это оптимистично
Ну не преувеличивай, так-то понятно чего он хочет.

Например:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <tuple>
#include <memory>
 
#include <windows.h>
 
template <class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch, Tr> & os, Tuple const & t, std::index_sequence<Is...>)
{
    using expander = int[];
    (void)expander{0, (void(os << ' ' << std::get<Is>(t)), 0)...};
}
 
template <typename ...Args>
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
    std::unique_ptr<std::tuple<Args...>> args{static_cast<std::tuple<Args...>*>(lpParam)};
    
    print_tuple(std::cout, *args, std::make_index_sequence<sizeof...(Args)>{});
    
    return 0;
}
 
template <typename ...Args>
HANDLE make_thread(Args && ...args)
{
    return CreateThread(NULL, 0, &MyThreadFunction<Args...>, new std::tuple<Args...>{std::forward<Args>(args)...}, 0, 0);
}
 
int main()
{
    auto thr = make_thread(1, 1.2, "test");
    
    WaitForSingleObject(thr, INFINITE);
}
Онлайн: https://rextester.com/LKJH69298


Добавлено ...
Или, например (более близко к задумке ТС):
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <tuple>
#include <memory>
#include <string>
 
#include <windows.h>
 
template <typename Tuple, std::size_t... Is>
void run(Tuple & data, std::index_sequence<Is...>)
{
    std::get<0>(data)(std::get<Is + 1>(data)...);
}
 
template <typename F, typename ...Args>
HANDLE make_thread(F lpStartAddress, Args && ...args)
{
    using ThreadRun = std::tuple<F, Args...>;
    
    auto threadRoutine = [](LPVOID lpParam) -> DWORD
    {
        std::unique_ptr<ThreadRun> data{static_cast<ThreadRun *>(lpParam)};
        run(*data, std::make_index_sequence<sizeof...(Args)>{});
        return 0;
    };
    return CreateThread(NULL, 0, threadRoutine, new ThreadRun{lpStartAddress, std::forward<Args>(args)...}, 0, 0);
}
 
int main()
{
    auto func = [](int a, double b, std::string const & c) 
    { 
        std::cout << a << " " << b << " " << c; 
    };
    auto thr = make_thread(func, 1, 3.14, "hello world");
    
    WaitForSingleObject(thr, INFINITE);
}
Онлайн: https://rextester.com/YLF74098
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 21:00  [ТС] 8
Похоже

Добавлено через 1 минуту
Ошибки были из-за набора инструментов сборки.
0
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
14.05.2019, 21:07 9
Цитата Сообщение от Timon32 Посмотреть сообщение
Ошибки были из-за набора инструментов сборки.
Смотря какие. Код, который вы выше показывали, все равно некорректный был - хоть с каким набором инструментов сборки.
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 21:08  [ТС] 10
Это собралось.
C++
1
template < class ... Types >  struct Tuple { } ;
0
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
14.05.2019, 21:18 11
Цитата Сообщение от Timon32 Посмотреть сообщение
Это собралось.
Да это понятно, но это только четверть дела же, учитывая код с потоком, который вы показали вначале.

Добавлено через 3 минуты
Цитата Сообщение от Timon32 Посмотреть сообщение
st::Thread::set
Если сейчас ошибок нет, то, вероятно, вы свою функцию set еще не вызывали. Попробуйте вызвать ее и увидите.
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 21:21  [ТС] 12
Я знаю что она не работает

Добавлено через 26 секунд
Как можно сохранить аргументы?
C++
1
2
3
4
5
6
7
template<class ... Args>
    struct ArgsContainer
    {
        ArgsContainer(Args&&... _args) : args(_args...) {}
 
        Args args;
    };
Добавлено через 49 секунд
Ошибка: "Args": пакет параметров должен раскрываться в этом контексте
0
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
14.05.2019, 21:29 13
Цитата Сообщение от Timon32 Посмотреть сообщение
Как можно сохранить аргументы?
Я выше показал как Используйте std::tuple для этого.
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
14.05.2019, 22:09  [ТС] 14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template <typename Tuple, size_t... Is>
void st::Thread::run(Tuple & data, std::index_sequence<Is...>)
{
    std::get<0>(data)(std::get<Is + 1>(data)...);
}
 
template <typename F, typename ...Args>
HANDLE st::Thread::make_thread(F lpStartAddress, Args && ...args)
{
    using ThreadRun = std::tuple<F, Args...>;
 
    auto threadRoutine = [](LPVOID lpParam) -> DWORD
    {
        std::unique_ptr<ThreadRun> data{ static_cast<ThreadRun *>(lpParam) };
        run(*data, std::make_index_sequence<sizeof...(Args)>{});
        return 0;
    };
    return handle = CreateThread(NULL, 0, threadRoutine, new ThreadRun{ lpStartAddress, std::forward<Args>(args)... }, CREATE_SUSPENDED, (LPDWORD)&id);
}
Ошибка:
warning C4573: для использования "st::Thread::run" требуется, чтобы компилятор передал "this", однако текущий режим передачи по умолчанию запрещает это
1> Исходный код.cpp(34): note: см. ссылку на создание экземпляров функции шаблон при компиляции "HANDLE *st::Thread::make_thread<void(__cdecl *)(int,int),int,int>(F,int &&,int &&)"
1> with
1> [
1> F=void (__cdecl *)(int,int)
1> ]
1>Thread.h(55): error C2352: st::Thread::run: недопустимый вызов нестатической функции-члена
0
6072 / 4061 / 1657
Регистрация: 07.05.2019
Сообщений: 12,575
Записей в блоге: 1
14.05.2019, 22:56 15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
using TFunc = std::function<void()>;
static 
void ThreadProc(void *p)
{
     std::unique_ptr<TFunc> fn(static_cast<TFunc *>(p)); 
      (*fn)();
}
 
template <typename F, typename ...Args>
HANDLE st::Thread::make_thread(F &&func, Args && ...args)
{
    return handle = CreateThread(NULL, 0, &ThreadProc, new TFunc(std::bind(func, args...)), CREATE_SUSPENDED, (LPDWORD)&id);
}
1
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
14.05.2019, 23:50 16
Лучший ответ Сообщение было отмечено Timon32 как решение

Решение

Цитата Сообщение от Timon32 Посмотреть сообщение
Ошибка
В этом коде run должен быть static (добавляете его только в объявлении).
0
0 / 0 / 0
Регистрация: 18.07.2015
Сообщений: 76
15.05.2019, 10:33  [ТС] 17
C++
1
new ThreadRun{ lpStartAddress, std::forward<Args>(args)... }
Как для этого вызвать delete?

Добавлено через 5 минут
В деструкторе
0
13890 / 7424 / 1761
Регистрация: 30.01.2014
Сообщений: 12,420
15.05.2019, 12:47 18
Цитата Сообщение от Timon32 Посмотреть сообщение
Как для этого вызвать delete?
Там же unique_ptr в функции потока. Поток завершится и память эта тоже освободится.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.05.2019, 12:47

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Тип функции с любым количеством аргументов
Здравствуйте! Подскажите, могу ли я сделать такой тип, который хранит функции с любой...

Динамический вызов разных методов класса с разным количеством аргументов
Здравствуйте, возникла такая проблема. У меня есть класс в котором есть несколько методов которые...

Исправить ошибку компиляции "для использования класса шаблон требуется список аргументов шаблона"
Решил создать класс List для задания двусвязного списка, и в самом начале компилятор начал ругаться...

Как написать лямбду с любым количеством параметров?
var x: integer; f: integer-&gt;integer := x -&gt; x &gt;= 0 ? x : -x; mult: (x,y: integer): integer...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.