Форум программистов, компьютерный форум CyberForum.ru

Переменное число аргументов - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.71
Pure
 Аватар для Pure
228 / 49 / 2
Регистрация: 13.03.2012
Сообщений: 453
Записей в блоге: 7
14.08.2012, 14:11     Переменное число аргументов #1
РАСПАКОВКА
есть ли способы кроме рекурсии и передачи как списка инициализации?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.08.2012, 14:11     Переменное число аргументов
Посмотрите здесь:

Дано целое число. Вывести его строку-описание вида «отрицательное чет-ное число», «нулевое число», «положительное нечетное число» и т. д. C++
C++ Передача аргументов в ф-ию
Есть функция с кучей аргументов, как её вызвать в другой функции (если половины аргументов у меня нет)? C++
C++ Можно ли в цикле for устанавливать переменное значение инициализатора?
Переменное число параметров функции - трабл с int C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.08.2012, 12:59     Переменное число аргументов #21
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Pure, Как вариант.

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
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <tuple>
#include <iostream>
 
template<typename T>
struct func
{
   func(const T& t):
      seq(t)
   {
   }
   template<typename U>
   void operator () (const U&)
   {
      std::cout << std::get<U::value>(seq) << std::endl;
   }
   T seq;
};
 
int main()
{
   auto t = std::make_tuple(1, 2, "hello", 5.6);
   boost::mpl::range_c<int, 0, std::tuple_size<decltype(t)>::value> range;
   boost::mpl::for_each<decltype(range)>(func<decltype(t)>(t));
}
Можно и не писать функтор, но что-то я плохо дружу с бустовскими лямбдами(

Добавлено через 41 минуту
~OhMyGodSoLong~, Это все хорошо, но boost::any довольно неудобен в использовании, все-таки any_cast постоянно юзать не очень радует + это все-таки абсолютно разные вещи, std::vector<boost::any> вектор объектов, в то время как T... раскрывается в типы напрямую, то есть такое с any не напишешь

C++
1
2
3
4
5
6
7
8
9
10
11
template<typename T, class... Args>
std::vector<T> create_vector(const Args&... args)
{
    return std::vector<T>(args...);
}
 
int main()
{
    const auto& v1 = create_vector<int>(5);
    const auto& v2 = create_vector<int>(5, 4);
}
А чтобы сделать так, чтобы аргументы хранились как ты сказал и удобно использовались нужна рефлексия
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
15.08.2012, 13:30
  #22

Не по теме:

Цитата Сообщение от Pure Посмотреть сообщение
давай вынесем твои поиски в этом направлении в твой блог
А Смысл?Я всего лишь написал вчера предположительную реализацию по твоему заданию (верней как понял его да ещё и без VA , сам же я стороник cstdarg). Будет время подумаю ещё...

Pure
 Аватар для Pure
228 / 49 / 2
Регистрация: 13.03.2012
Сообщений: 453
Записей в блоге: 7
15.08.2012, 13:44  [ТС]     Переменное число аргументов #23
ForEveR, т.е. итоговое решение выглядит так

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
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <tuple>
#include <iostream>
 
template<typename T>
struct func
{
   func(const T& t):
      seq(t)
   {
   }
   template<typename U>
   void operator () (const U&)
   {
      std::cout << std::get<U::value>(seq) << std::endl;
   }
   T seq;
};
 
 
template<class... Args>
void consume_done (Args... args)
{
   std::tuple<Args...> t{args...};
    boost::mpl::range_c<int, 0, std::tuple_size<decltype(t)>::value> range;
   boost::mpl::for_each<decltype(range)>(func<decltype(t)>(t));
  
} 
int main()
{  
  consume_done("5555",6.7,'Z',67);  
}
чтож, некрасиво выглядит, но работает. спасибо за то что потратил время и поморочился.

луета конечно какая то. перепаковка тупла в рендж. скрестили бы сразу и то и другое в стандарте.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
15.08.2012, 13:53     Переменное число аргументов #24
ForEveR, я и не говорил, что оно замена статическому варианту. Ваш вариант для Pure сломается же ещё на стадии компиляции, если в кортеж засунуть что-то, что ostream не умеет выводить. Для полного счастья ещё бы отделить сам функтор от вот этого T seq;, но что-то у меня пока не выходит.

Для удобной динамической типизации надо рефлексию, а в Си++ её нет и не будет, пока темлейты будут кушаться при компиляции. Ну и, естественно, это потребует переделывать механику вызова функций.

Ну, и это только подтверждает, что за этими всеми плюшками надо идти в динамические языки. Или в Хаскелл — у него выводилка типов достаточно умная.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.08.2012, 15:19     Переменное число аргументов #25
Pure, Ну тут нет перепаковки. Рейндж используется исключительно для индексов.
~OhMyGodSoLong~, Ну да. Слом на этапе компиляции - это не так уж и плохо. Можно конечно SFINAE задействовать как-нибудь... Ща поковыряюсь ради интереса. Ну рефлексию-то очень даже предлагают ввести (говорил Страуструп что-то на эту тему). А так конечно с динамическими языками не сравнится.

Добавлено через 1 час 25 минут
Ну как-то так, но не сомневаюсь что можно и проще.

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/for_each.hpp>
#include <tuple>
#include <iostream>
 
template<typename T, size_t Idx, typename Enabled = void>
struct is_printable
{
   static constexpr bool value = false;
};
 
template<typename T, size_t Idx>
struct is_printable<T, Idx,
   typename std::enable_if<std::is_lvalue_reference<decltype(std::cout << std::get<Idx>(T()))>::value>::type>
{
   static constexpr bool value = true;
};
 
template<typename T>
struct func
{
   func(const T& arg):
      seq(arg)
   {
   }
 
   template<typename U, typename Enabled = void>
   struct func_impl
   {
      template<typename Seq>
      static void apply(const Seq& seq) { }
   };
 
   template<typename U>
   struct func_impl<U, typename std::enable_if<is_printable<T, U::value>::value>::type>
   {
      template<typename Seq>
      static void apply(const Seq& seq) { std::cout << std::get<U::value>(seq) << std::endl; }
   };
 
   template<typename U>
   void operator () (const U&)
   {
      func_impl<U>::apply(seq);
   }
 
   T seq;
};
 
struct A
{
};
 
struct B
{
};
 
int main()
{
   auto t = std::make_tuple(A(), 1, 2, "hello", B(), 5.6);
   boost::mpl::range_c<int, 0, std::tuple_size<decltype(t)>::value> range;
   boost::mpl::for_each<decltype(range)>(func<decltype(t)>(t));
}
http://liveworkspace.org/code/6ecd7f...15e4b4bc39897b
Pure
 Аватар для Pure
228 / 49 / 2
Регистрация: 13.03.2012
Сообщений: 453
Записей в блоге: 7
15.08.2012, 15:52  [ТС]     Переменное число аргументов #26
Сообщение было отмечено автором темы, экспертом или модератором как ответ
хотя ерунда. сейчас опять. std::get<1> std::get<2>.

снимаю задачу.

из всего диалога какие выводы напросились.

1. если на этапе компиляции есть все исходные данные то работая std::get можно спокойно окучивать кортеж, который принял переменный список.
2. индексации по кортежу нормальной не было сделано. достаточно посмотреть монстрокод нужный для прохода. возникает вопрос а не зарыта ли глубоко в буст рекурсия? Если нет то что мешало сделать индексы кортежу.

будь мужиком ставь лайк
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.08.2012, 16:16     Переменное число аргументов #27
Pure, Зарыта конечно. Шаблонное метапрограммирование на С++ в любом случае сводится к рекурсивной раскрутке шаблонов.
for_each к примеру.
mpl::for_each
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
template< bool done = true >
struct for_each_impl
{
    template<
          typename Iterator
        , typename LastIterator
        , typename TransformFunc
        , typename F
        >
    static void execute(
          Iterator*
        , LastIterator*
        , TransformFunc*
        , F
        )
    {
    }
};
 
template<>
struct for_each_impl<false>
{
    template<
          typename Iterator
        , typename LastIterator
        , typename TransformFunc
        , typename F
        >
    static void execute(
          Iterator*
        , LastIterator*
        , TransformFunc* 
        , F f
        )
    {
        typedef typename deref<Iterator>::type item;
        typedef typename apply1<TransformFunc,item>::type arg;
    
        // dwa 2002/9/10 -- make sure not to invoke undefined behavior
        // when we pass arg.
        value_initialized<arg> x;
        aux::unwrap(f, 0)(boost::get(x));
        
        typedef typename mpl::next<Iterator>::type iter;
        for_each_impl<boost::is_same<iter,LastIterator>::value>
            ::execute( static_cast<iter*>(0), static_cast<LastIterator*>(0), static_cast<TransformFunc*>(0), f);
    }
};
 
} // namespace aux
 
// agurt, 17/mar/02: pointer default parameters are necessary to workaround 
// MSVC 6.5 function template signature's mangling bug
template<
      typename Sequence
    , typename TransformOp
    , typename F
    >
inline
void for_each(F f, Sequence* = 0, TransformOp* = 0)
{
    BOOST_MPL_ASSERT(( is_sequence<Sequence> ));
 
    typedef typename begin<Sequence>::type first;
    typedef typename end<Sequence>::type last;
 
    aux::for_each_impl< boost::is_same<first,last>::value >
        ::execute(static_cast<first*>(0), static_cast<last*>(0), static_cast<TransformOp*>(0), f);
}
 
template<
      typename Sequence
    , typename F
    >
inline
void for_each(F f, Sequence* = 0)
{
    for_each<Sequence, identity<> >(f);
}
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
15.08.2012, 16:35     Переменное число аргументов #28
Цитата Сообщение от Pure Посмотреть сообщение
2. индексации по кортежу нормальной не было сделано. достаточно посмотреть монстрокод нужный для прохода. возникает вопрос а не зарыта ли глубоко в буст рекурсия? Если нет то что мешало сделать индексы кортежу.
ты не понимаешь в чем разница в разборе динамических и статических кортежей
"обыкновенного" статического перебора кортежа просто не может быть
Pure
 Аватар для Pure
228 / 49 / 2
Регистрация: 13.03.2012
Сообщений: 453
Записей в блоге: 7
15.08.2012, 16:51  [ТС]     Переменное число аргументов #29
Цитата Сообщение от ForEveR Посмотреть сообщение
Pure, Зарыта конечно.
тогда в чем отличие от самого первого поста? столько строк и все напрасно-результат такой же
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
15.08.2012, 16:51     Переменное число аргументов #30
Pure, В том, что используются готовые алгоритмы. Нерекурсивных вариантов нет и быть не может.
Pure
15.08.2012, 16:53  [ТС]
  #31

Не по теме:

alex_x_x, скажи а у тебя когда нибудь было повреждено ухо?

alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
15.08.2012, 20:30     Переменное число аргументов #32
Pure, нет а шо?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.08.2012, 23:42     Переменное число аргументов
Еще ссылки по теме:

C++ Программа должна читать из консоли переменное кол-во аргументов и выводить их
C++ Составить функцию, принимающую переменное количество параметров
Переменное число параметров шаблона C++

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

Или воспользуйтесь поиском по форуму:
Pure
15.08.2012, 23:42  [ТС]     Переменное число аргументов
  #33

Не по теме:

alex_x_x, да просто был у нас один парень.думали ухо у него повреждено. а потом выяснилось что все нормально с ухом было. чем то по стилю на тебя похож. покажи фотку

Yandex
Объявления
15.08.2012, 23:42     Переменное число аргументов
Ответ Создать тему
Опции темы

Текущее время: 14:29. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru