Вызов функции с переменным числом параметров
От: unreg_flex  
Дата: 19.02.10 11:55
Оценка: :))
void a(...)
{
  // some stuff ...
}

void b(...)
{
  // тут хочу вызвать a(...) с теми же аргументами
}


как?
Re: Вызов функции с переменным числом параметров
От: unreg_flex  
Дата: 19.02.10 12:03
Оценка:
почти уверен что никак, но все же ...
Re[2]: Вызов функции с переменным числом параметров
От: rising_edge  
Дата: 19.02.10 12:05
Оценка: +1
Здравствуйте, unreg_flex, Вы писали:

_>почти уверен что никак, но все же ...


А поиском по сайту пробовали пользоваться? Тема обсуждалась неоднократно.
Re: Вызов функции с переменным числом параметров
От: Мишень-сан  
Дата: 19.02.10 12:07
Оценка: 3 (1)
Здравствуйте, unreg_flex, Вы писали:

_>как?


так

void av(va_list args)
{
  // do stuff using va_arg macro
}

void a(...)
{
  va_list args;
  va_start(args, 0); // тут не уверен что ноль,
                     //  возможно, работает только для функций с 1+ аргументами,
                     //  т.е. должен быть хоть один именованный аргумент
  av(args);
}

void b(...)
{
  va_list args;
  va_start(args, 0);
  av(args);
}
Re: Вызов функции с переменным числом параметров
От: посетитель /life/  
Дата: 19.02.10 12:12
Оценка: 3 (1) :))
Здравствуйте, unreg_flex, Вы писали:

_>
_>void a(...)
_>{
_>  // some stuff ...
_>}

_>void b(...)
_>{
_>  // тут хочу вызвать a(...) с теми же аргументами
_>}
_>


_>как?


http://www.rsdn.ru/forum/cpp/2701675.1.aspx
Автор: Roman Odaisky
Дата: 22.10.07
Re[3]: Вызов функции с переменным числом параметров
От: unreg_flex  
Дата: 19.02.10 12:18
Оценка:
Здравствуйте, rising_edge, Вы писали:

_>Здравствуйте, unreg_flex, Вы писали:


_>>почти уверен что никак, но все же ...


_>А поиском по сайту пробовали пользоваться? Тема обсуждалась неоднократно.


Пользовался поиском по мсдну, как бэ мне показалось что там вероятнее это найти, однако на такое:

void av(va_list args)
{
  // do stuff using va_arg macro
}


я там не напоролся
Re: Вызов функции с переменным числом параметров
От: achp  
Дата: 19.02.10 12:31
Оценка: :))
Здравствуйте, unreg_flex, Вы писали:

_>
_>void a(...)
_>{
_>  // some stuff ...
_>}

_>void b(...)
_>{
_>  // тут хочу вызвать a(...) с теми же аргументами
_>}
_>


Раз плюнуть!

template<typename... T>
void a(T... v)
{
    //...
}

template<typename... T>
void b(T... v)
{
    a(v...);
}


Re[2]: Вызов функции с переменным числом параметров
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 19.02.10 15:36
Оценка: 1 (1)
Здравствуйте, achp, Вы писали:

A>


Фулюган!
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re: Вызов функции с переменным числом параметров
От: jerry_ru  
Дата: 19.02.10 17:59
Оценка:
Здравствуйте, unreg_flex, Вы писали:

_>
_>void a(...)
_>{
_>  // some stuff ...
_>}

_>void b(...)
_>{
_>  // тут хочу вызвать a(...) с теми же аргументами
_>}
_>


_>как?



ну можно так:

//Здесь указатели
void a(int* b...)
{
    std::cerr<<*b<<std::endl;
    ++b;
    std::cerr<<*b<<std::endl;
    ++b;
    std::cerr<<*b<<std::endl;
}

//Здесь значения:
void b(int i...)
{
    int * ptr = &i;

    std::cerr<<*ptr<<std::endl;
    ++ptr;
    std::cerr<<*ptr<<std::endl;
    ++ptr;
    std::cerr<<*ptr<<std::endl;

    a(&i);
}

int main(int argc, char* argv[])
{

int i = 15;
int i2 = 99;
int i3 = 999;

b( i, i2, i3);

}
Re[2]: Вызов функции с переменным числом параметров
От: alexeiz  
Дата: 21.02.10 02:40
Оценка: 36 (2)
Здравствуйте, achp, Вы писали:

A>Раз плюнуть!


A>
A>template<typename... T>
A>void a(T... v)
A>{
A>    //...
A>}

A>template<typename... T>
A>void b(T... v)
A>{
A>    a(v...);
A>}
A>


A>


Хаха, а вот и нет! А аргументы кто форвардить будет? И возвращаемое значение было бы неплохо вывести тоже.
template <typename ... Args>
auto b(Args && ... args) -> decltype(a(std::forward<Args>(args) ...))
{
    return a(std::forward<Args>(args) ...);
}
Re[3]: Вызов функции с переменным числом параметров
От: achp  
Дата: 22.02.10 11:12
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Хаха, а вот и нет! А аргументы кто форвардить будет? И возвращаемое значение было бы неплохо вывести тоже.

A>
A>template <typename ... Args>
A>auto b(Args && ... args) -> decltype(a(std::forward<Args>(args) ...))
A>{
A>    return a(std::forward<Args>(args) ...);
A>}
A>


Ну, уж это если совсем по-грамотному. Мы-то люди простые, у нас функции void возвращают, и никаких тебе &&.
Re[2]: Вызов функции с переменным числом параметров
От: unreg_flex  
Дата: 24.02.10 08:15
Оценка:
Здравствуйте, achp, Вы писали:

A>Раз плюнуть!


A>
A>template<typename... T>
A>void a(T... v)
A>{
A>    //...
A>}

A>template<typename... T>
A>void b(T... v)
A>{
A>    a(v...);
A>}
A>


A>


Чур меня, чур
Ну вас нафик с вашими технологиями
Re[3]: Вызов функции с переменным числом параметров
От: alexeiz  
Дата: 25.02.10 06:21
Оценка:
Здравствуйте, unreg_flex, Вы писали:

_>Здравствуйте, achp, Вы писали:


A>>Раз плюнуть!


A>>
A>>template<typename... T>
A>>void a(T... v)
A>>{
A>>    //...
A>>}

A>>template<typename... T>
A>>void b(T... v)
A>>{
A>>    a(v...);
A>>}
A>>


A>>


_>Чур меня, чур

_>Ну вас нафик с вашими технологиями

А что такого страшного? Трех маленьких точечек испугалси?
Re[4]: Вызов функции с переменным числом параметров
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 25.02.10 15:43
Оценка:
Здравствуйте, achp, Вы писали:

A>Здравствуйте, alexeiz, Вы писали:


A>>Хаха, а вот и нет! А аргументы кто форвардить будет? И возвращаемое значение было бы неплохо вывести тоже.

A>>
A>>template <typename ... Args>
A>>auto b(Args && ... args) -> decltype(a(std::forward<Args>(args) ...))
A>>{
A>>    return a(std::forward<Args>(args) ...);
A>>}
A>>


A>Ну, уж это если совсем по-грамотному. Мы-то люди простые, у нас функции void возвращают, и никаких тебе &&.

как это работает?
Sic luceat lux!
Re[5]: Вызов функции с переменным числом параметров
От: alexeiz  
Дата: 25.02.10 19:48
Оценка:
Здравствуйте, Kernan, Вы писали:

A>>>
A>>>template <typename ... Args>
A>>>auto b(Args && ... args) -> decltype(a(std::forward<Args>(args) ...))
A>>>{
A>>>    return a(std::forward<Args>(args) ...);
A>>>}
A>>>

K>как это работает?

Здесь применяется несколько новых C++0x концепций:

1. rvalue references (&&, или двойной претцель )
2. perfect argument forwarding (std::forward + &&)
3. вывод возвращаемого значения функции (decltype)
4. variadic templates (typename...)

Каждая требует отдельного объяснения. Что тебя больше всего интересует?
Re: Вызов функции с переменным числом параметров
От: Roman Odaisky Украина  
Дата: 25.02.10 21:20
Оценка:
Здравствуйте, unreg_flex, Вы писали:

_> // тут хочу вызвать a(...) с теми же аргументами


Спасибо, коллекцию пополнил. Еще не все забыли, что у нас вики есть? http://wiki.rsdn.ru/ellipsis.ashx
До последнего не верил в пирамиду Лебедева.
Re[3]: std::forward
От: Roman Odaisky Украина  
Дата: 25.02.10 21:22
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>А аргументы кто форвардить будет?

A>
A>template <typename ... Args>
A>auto b(Args && ... args) -> decltype(a(std::forward<Args>(args) ...))
A>{
A>    return a(std::forward<Args>(args) ...);
A>}
A>

Вот! Тебя-то мне и надо! Хоть ты сможешь по-человечески растолковать, что же делает std::forward, зачем ей явно указывать шаблонный параметр и зачем она вообще нужна?
До последнего не верил в пирамиду Лебедева.
Re[4]: std::forward
От: Masterkent  
Дата: 10.03.10 22:31
Оценка: 77 (8)
Roman Odaisky:

RO>что же делает std::forward, зачем ей явно указывать шаблонный параметр и зачем она вообще нужна?


Порой возникает задача: передать аргументы некоей функции-оболочки другой функции (возможно, перегруженной) так, чтобы результат вызова функции-оболочки был практически идентичен вызову этой другой функции с теми же самыми аргументами.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm:

The general form of the forwarding problem is that in the current language,

For a given expression E(a1, a2, ..., an) that depends on the (generic) parameters a1, a2, ..., an, it is not possible to write a function (object) f such that f(a1, a2, ..., an) is equivalent to E(a1, a2, ..., an).

В общем случае эта проблема остаётся неразрешимой и в C++0x (см. Perfect Forwarding Failure Cases), но rvalue-ссылки позволяют значительно приблизиться к идеалу.

Аргумент функции — это по определению какое-то выражение. Каждое выражение обладает следующими свойствами:
1) тип,
2) принадлежность к lvalues или rvalues,
3) принадлежность к битовым полям,
4) принадлежность к константным выражениям.

Возможно, есть ещё что-то. Идеальная пересылка аргумента подразумевает как минимум сохранение этих четырёх свойств. С помощью rvalue-ссылок C++0x предоставит возможность сохранять два из них:
1) тип,
2) принадлежность к lvalues (иногда именуемая как lvalueness).

Для сохранения типа ничего особенного делать не нужно, а вот чтобы сохранить lvalueness, приходится выполнять кое-какое преобразование. Прежде всего, нужно отметить следующее:

N3035 — 5/6:

If an expression initially has the type “rvalue reference to T” (8.3.2, 8.5.3), the type is adjusted to “T” prior to any further analysis, and the expression designates the object or function denoted by the rvalue reference. If the expression is the result of calling a function, whether implicitly or explicitly, it is an rvalue; otherwise, it is an lvalue.

5.2.9/1:

The result of the expression static_cast<T>(v) is the result of converting the expression v to type T. If T is an lvalue reference type, the result is an lvalue; otherwise, the result is an rvalue.

Как видно, именованные ссылки — всегда lvalues. Это значит, что если мы запишем так:

template <class T>
    void f(T &&t)
        { E(t); }

то не получим адекватной пересылки rvalue (аргументом для E всегда будет lvalue):

struct X {};

void E(A &&)      { std::cout << "E(A &&)\n"; }
void E(A const &) { std::cout << "E(A const &)\n"; }

template <class T>
    void f(T &&t)
        { E(t); } // t is lvalue

int main()
{
    E(A()); // calls E(A &&)
    f(A()); // calls E(A const &)
}

Для пересылки аргумента с сохранением принадлежности к lvalues/rvalues нам нужно получать из t rvalue-выражение, когда аргументом f передаётся rvalue. Этим и занимается std::forward.

struct A {};

void E(A &&)      { std::cout << "E(A &&)\n"; }
void E(A const &) { std::cout << "E(A const &)\n"; }

template <class T>
    void f(T &&t)
        { E(std::forward<T>(t)); }

int main()
{
    A a;

    E(a);   // calls E(A const &)

    f(a);   // calls E(A const &)
            // T is deduced to be "lvalue reference to A"
            // f<A &>'s function parameter is "lvalue reference to A"

    E(A()); // calls E(A &&)

    f(A()); // calls E(A &&)
            // T is deduced to be "A"
            // f<A>'s function parameter is "rvalue reference to A"
}

Выведенный шаблонный аргумент для параметра T зависит от принадлежности аргумента, переданного в f, к lvalue: если аргумент — lvalue типа A, то шаблонный аргумент, выведенный для T, будет "lvalue reference to A"; если аргумент — rvalue типа A, то шаблонный аргумент, выведенный для T, будет просто "A" (см. 14.9.2.1/3). В первом случае попытка формирования ссылки на ссылку приводит к сокращению ссылок (см. 14.4.1/4), т.е. rvalue-ссылка на lvalue-ссылку типа A превращается в lvalue-ссылку типа A. Приведу выдержки из правил:

14.9.2.1/1:

Template argument deduction is done by comparing each function template parameter type (call it P) with the type of the corresponding argument of the call (call it A) as described below.

14.9.2.1/3:

If P is an rvalue reference to a cv-unqualified template parameter and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction. [ Example:

template <typename T> int f(T&&);
int i;
int j = f(i);                          // calls f<int&>(i)
template <typename T> int g(const T&&);
int k;
int n = g(k);                          // calls g<int>(k)

—end example ]

14.4.1/4:

If a template-argument for a template-parameter T names a type that is a reference to a type A, an attempt to create the type “lvalue reference to cv T” creates the type “lvalue reference to A,” while an attempt to create the type “rvalue reference to cv T” creates the type T [ Example:

template <class T> class X {
  void f(const T&);
  void g(T&&);
};
X<int&> x1;                 // X<int&>::f has the parameter type int&
                            // X<int&>::g has the parameter type int&
X<const int&&> x2;          // X<const int&&>::f has the parameter type const int&
                            // X<const int&&>::g has the parameter type const int&&

—end example ]

Впрочем, следует ожидать, что в будущем концепция lvalue и rvalue претерпит некоторые изменения — см. N3030.
Re[3]: Вызов функции с переменным числом параметров
От: TimurSPB Интернет  
Дата: 10.03.10 22:41
Оценка:
_>Чур меня, чур
_>Ну вас нафик с вашими технологиями

Изучай технологии, а то так и будешь всю жизнь ключи подавать.
Make flame.politics Great Again!
Re[5]: std::forward
От: Roman Odaisky Украина  
Дата: 10.03.10 23:58
Оценка:
Здравствуйте, Masterkent, Вы писали:

M>template <class T>
M>    void f(T &&t)
M>        { E(std::forward<T>(t)); }


M>Выведенный шаблонный аргумент для параметра T зависит от принадлежности аргумента, переданного в f, к lvalue: если аргумент — lvalue типа A, то шаблонный аргумент, выведенный для T, будет "lvalue reference to A"; если аргумент — rvalue типа A, то шаблонный аргумент, выведенный для T, будет просто "A" (см. 14.9.2.1/3).


Ага. Т. е., если бы std::forward не принимала явно тип T, то ей было бы никак не узнать, на lvalue ли ссылается t, потому что t во всех отношениях похожа на обычную &-ссылку?

И еще, при A const ca; f(ca); будет T = A const &? Тогда при template <class X> void r(X &), что ли, можно вызывать r(ca) и получить X = A const? Как-то странно смотрится.
До последнего не верил в пирамиду Лебедева.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.