auto in argument list
От: D14  
Дата: 12.07.09 07:57
Оценка:
Балуюсь Intel C++.
Так можно.
#include <iostream>
#include <algorithm>
#include <vector>

int main()
{   
    double arr[]={1,2.5,3,4,5};
    std::vector<double> v(arr,arr+5);
    typedef decltype(v[0]) ElemType;
    std::for_each(v.begin(),v.end(),[&](ElemType e){std::cout << e << " " ;});  
    std::cout << std::endl;
    for (auto it = v.begin(),end=v.end(); it !=end; ++it)    
    {
        std::cout << *it << " " ;
    }
    std::cout << std::endl;  
    return 0;
}

А так нельзя
    std::for_each(v.begin(),v.end(),[&](auto e){std::cout << e << " " ;});

Так ПОКА нельзя, или вообще никогда можно не будет?
c++0x
Re: auto in argument list
От: byleas  
Дата: 12.07.09 08:11
Оценка:
Здравствуйте, D14, Вы писали:

D14>Так ПОКА нельзя, или вообще никогда можно не будет?

Ну может, в каком-нить C++2x.. Ибо тип auto выводится при инициализации, а параметры не инициализируются в compile-time. Это же не boost::any.
Re[2]: auto in argument list
От: D14  
Дата: 12.07.09 08:29
Оценка:
Здравствуйте, byleas, Вы писали:

B>Ну может, в каком-нить C++2x.. Ибо тип auto выводится при инициализации, а параметры не инициализируются в compile-time. Это же не boost::any.

При инициализации это как?
Так тоже нельзя.
auto f = [&](auto e){double t=1.01; e=t; std::cout << e << " " ;};

А так можно
struct PrintElement
{
template<class T>
void operator()(const T& e){std::cout << e << " ";}
};
...
std::for_each(v.begin(),v.end(),PrintElement());
Re: auto in argument list
От: Peter K.  
Дата: 12.07.09 10:37
Оценка:
Здравствуйте, D14, Вы писали:

D14>Балуюсь Intel C++.

D14>А так нельзя
D14>
D14>    std::for_each(v.begin(),v.end(),[&](auto e){std::cout << e << " " ;});  
D14>

D14>Так ПОКА нельзя, или вообще никогда можно не будет?
А так в Intel C++ можно?
   for (auto e: v) { std::cout << e << " "; }
Re[2]: auto in argument list
От: D14  
Дата: 12.07.09 11:14
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>А так в Intel C++ можно?

PK>
PK>   for (auto e: v) { std::cout << e << " "; }
PK>

Увы.
Re[3]: auto in argument list
От: byleas  
Дата: 12.07.09 14:01
Оценка:
Здравствуйте, D14, Вы писали:

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


B>>Ну может, в каком-нить C++2x.. Ибо тип auto выводится при инициализации, а параметры не инициализируются в compile-time. Это же не boost::any.

D14>При инициализации это как?
N2800:

7.1.6.4/1
The auto type-specifier signifies that the type of an object being declared shall be deduced from its initializer or specified explicitly at the end of a function declarator.

7.1.6.4/3
… The decl-specifier-seq shall be followed by one or more init-declarators, each of which shall have a non-empty initializer of either of the following forms:
= assignment-expression
( assignment-expression )

Re[2]: auto in argument list
От: byleas  
Дата: 12.07.09 14:23
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>А так в Intel C++ можно?

С этим и в комитете ещё не определились.
Re[4]: auto in argument list
От: D14  
Дата: 12.07.09 18:55
Оценка:
Здравствуйте, byleas, Вы писали:

B>7.1.6.4/1

B>7.1.6.4/3

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

    auto id=[](int x){return x;};
    typedef decltype(id) inttoint;
    auto compose=[](inttoint f, inttoint g){return [=](int x){ return f(g(x));}; };
    inttoint cid(compose(id,id)); //Тут не едут лыжи!
    std::cout << cid(10) << std::endl;
Re[5]: auto in argument list
От: byleas  
Дата: 12.07.09 19:44
Оценка:
Здравствуйте, D14, Вы писали:

D14>Балуюсь только. Многое не очевидно, например

Ну, во-первых, каждое лямбда-выражение — это новый тип. Во-вторых, не виден контекст кода, и получилось что-то вроде мудрёного регулярного выражения (regexp), непонятно, что хотели сделать
Re[6]: auto in argument list
От: D14  
Дата: 12.07.09 20:22
Оценка:
Здравствуйте, byleas, Вы писали:

B>Ну, во-первых, каждое лямбда-выражение — это новый тип.

Ясно. Если новый тип, то выходит, что функцию, принимающая параметром лямбду продекларировать никак нельзя, значит она должна быть шаблонной.
Так обстоят дела с параметрами на вход. Но мне пока не ясно, как вернуть лямбду из функции?
Так ведь ничего не выйдет...
template <typename F>
F id()
{
    return [=](int x){return x;};
}


B>Во-вторых, не виден контекст кода, и получилось что-то вроде мудрёного регулярного выражения (regexp), непонятно, что хотели сделать

Композицию функций g(f(x))
Re: auto in argument list
От: jazzer Россия Skype: enerjazzer
Дата: 12.07.09 23:24
Оценка: 4 (1)
Здравствуйте, D14, Вы писали:

D14>А так нельзя

увы

D14>
D14>    std::for_each(v.begin(),v.end(),[&](auto e){std::cout << e << " " ;});  
D14>

D14>Так ПОКА нельзя, или вообще никогда можно не будет?
ПОКА точно нельзя.
Лямбды, добавленные в C++0x — не полиморфные.
Если ты посмотришь в материалы комитета, там лямбды добавлены в таком виде: "(monomorphic) Lambda expressions and closures for C++" со следующей формулировкой (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2413.pdf):

This document provides wording for monomorphic (non-generic) lambda functions, which we propose
for the committee to move forward with for C++0X. The discussion on polymorphic (generic) lambda
functions is not included in this document. Following the committee’s recommendation from the
Toronto meeting (July 2007), we separate the specification of polymorphic lambda functions into a
separate (later) document. Polymorphic lambda functions can be made upwards compatible with the
non-generic lambda functions proposed here.


Там возникает достаточно много проблем, описанных, например, здесь (см. раздел "Generic lambda functions"):
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2329.pdf
Главная проблема с тем, что мы можем лямбду сохранить в переменной, а потом использовать где угодно с какими угодно аругментами.

Также у нас ведь не существует возможности объявлять обычные функции с аргументами типа auto (для этого у нас есть только шаблоны, которые проверяются во время инстанцирования, а не во время объявления).
Ведь лямбда сама по себе — это просто объект-функтор с каким-то оператором() внутри, и вся возня идет с тем, как правильно этот объект сформировать и какие аргументы должны быть у оператора(). А так же чтоб реализовывался принцип наименьшего удивления, который сейчас не выполняется для шаблонов — ты объявил шаблон, ошибок не получил, потом заюзал его в каком-то далеком метсе и получил миллион ошибок из мест, о существовании которых ты и не подозревал.

Понятно, что в каком-то виде это все будет разрешено и у нас будут полиморфные лямбды (а может, auto в параметре будет обобщен и до обычных функций), но по соображениям синицы в руках (релиза стандарта в 2009-2010), у нас пока что будут только мономорфные лямбды.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: auto in argument list
От: alexeiz  
Дата: 13.07.09 03:50
Оценка:
Здравствуйте, D14, Вы писали:

D14>А так нельзя

D14>
D14>    std::for_each(v.begin(),v.end(),[&](auto e){std::cout << e << " " ;});  
D14>


Можно так:
std::for_each(v.begin(), v.end(), [] (decltype(*v.begin()) e) { std::cout << e << " "; });
Re[7]: auto in argument list
От: alexeiz  
Дата: 13.07.09 03:53
Оценка: +1
Здравствуйте, D14, Вы писали:

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


B>>Ну, во-первых, каждое лямбда-выражение — это новый тип.

D14>Ясно. Если новый тип, то выходит, что функцию, принимающая параметром лямбду продекларировать никак нельзя, значит она должна быть шаблонной.
D14>Так обстоят дела с параметрами на вход. Но мне пока не ясно, как вернуть лямбду из функции?
D14>Так ведь ничего не выйдет...
D14>
D14>template <typename F>
D14>F id()
D14>{
D14>    return [=](int x){return x;};
D14>}
D14>


function<int(int)> id()
{
    return [](int x) { return x; };
}
Re[2]: auto in argument list
От: D14  
Дата: 13.07.09 08:17
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Понятно, что в каком-то виде это все будет разрешено и у нас будут полиморфные лямбды (а может, auto в параметре будет обобщен и до обычных функций), но по соображениям синицы в руках (релиза стандарта в 2009-2010), у нас пока что будут только мономорфные лямбды.


Из соображений синицы в руках, почему бы для начала анонимные классы не ввести, как в Java. По-моему не сложно было бы реализовать.
...
std::for_each(v.begin(),v.end(),struct 
                                {
                                    template<class T>
                                    void operator()(const T& e){std::cout << e << " ";}
                                };
);


Проблему вижу в возможности зацикливания, но она и без этого есть.
template <class T> void f(T t)
{
f(struct{template<class T> void operator()(){t();t();}});
}
Re[3]: auto in argument list
От: byleas  
Дата: 13.07.09 08:43
Оценка:
Здравствуйте, D14, Вы писали:

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


J>>Понятно, что в каком-то виде это все будет разрешено и у нас будут полиморфные лямбды (а может, auto в параметре будет обобщен и до обычных функций), но по соображениям синицы в руках (релиза стандарта в 2009-2010), у нас пока что будут только мономорфные лямбды.


D14>Из соображений синицы в руках, почему бы для начала анонимные классы не ввести, как в Java. По-моему не сложно было бы реализовать.

А чем это отличается от локальных классов и чем это лучше лямбды? (ведь определяешь не весь класс, а только функцию (читай, оператор вызова))
Re[8]: auto in argument list
От: D14  
Дата: 13.07.09 09:02
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>
A>function<int(int)> id()
A>{
A>    return [](int x) { return x; };
A>}
A>


Посмотрю матчасть по этому вопросу подробнее, но на практике пользоваться этим пока нельзя.
Такой пример вылетает с access violation.

#include <boost/function.hpp>
#include <iostream>

typedef boost::function<int(int)> inttoint;

inttoint id()
{
    return [=](int x) { return x; };
}

int main()
{       
    auto compose=[](inttoint f, inttoint g){return [=](int x){ return f(g(x));}; };
    inttoint cid(compose(id(),id())); 
    std::cout << cid(10) << std::endl;

    return 0;
}
Re[4]: auto in argument list
От: D14  
Дата: 13.07.09 09:11
Оценка:
Здравствуйте, byleas, Вы писали:

B>А чем это отличается от локальных классов и чем это лучше лямбды? (ведь определяешь не весь класс, а только функцию (читай, оператор вызова))


— ИМХО просто встроить в язык.
— отсутствует проблема указанием типа параметра функции (хотя к сильному сокращению объема кода это не приведет).
— не является first-сlass object, не надо принимать на вход и возвращать. С лямбдами есть какой-то спец. тип function<int(int)> .
Re[9]: auto in argument list
От: alexeiz  
Дата: 13.07.09 10:03
Оценка:
Здравствуйте, D14, Вы писали:

D14>Посмотрю матчасть по этому вопросу подробнее, но на практике пользоваться этим пока нельзя.

D14>Такой пример вылетает с access violation.

У меня всё работает в VC++ 2010. function<> не из boost'а а из <functional> (C++0x).
Re[5]: auto in argument list
От: jazzer Россия Skype: enerjazzer
Дата: 13.07.09 10:24
Оценка:
Здравствуйте, D14, Вы писали:

D14>С лямбдами есть какой-то спец. тип function<int(int)> .


Это обычный boost::function
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: auto in argument list
От: CreatorCray  
Дата: 13.07.09 11:35
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>А так в Intel C++ можно?

PK>
PK>   for (auto e: v) { std::cout << e << " "; }
PK>


Можно так:

#define foreach(it,cont)    for (auto it = (cont).begin(), foreach_end_##it = (cont).end();it != foreach_end_##it;++it)

foreach(it, container)    {std::cout << *it << " ";}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[3]: auto in argument list
От: Аноним  
Дата: 13.07.09 11:40
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, Peter K., Вы писали:


PK>>А так в Intel C++ можно?

...
CC>Можно так:

CC>
CC>#define foreach(it,cont)    for (auto it = (cont).begin(), foreach_end_##it = (cont).end();it != foreach_end_##it;++it)

CC>foreach(it, container)    {std::cout << *it << " ";}
CC>


А можно и так:
#define foreach BOOST_FOREACH

Re[4]: auto in argument list
От: CreatorCray  
Дата: 13.07.09 12:00
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>А можно и так:

А>
А>#define foreach BOOST_FOREACH
А>

А>
Не, так нельзя
Придется буст подрубать
а это сильно больше одной строки -> минус скорости компиляции.
тем более бустовый форыч сильно громоздкий.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[10]: auto in argument list
От: D14  
Дата: 13.07.09 18:38
Оценка:
Здравствуйте, alexeiz, Вы писали:


A>У меня всё работает в VC++ 2010. function<> не из boost'а а из <functional> (C++0x).


С typedef std::tr1::function<int(int)> inttoint; в MSVC++ 2008 + SP тот же access violation в каком-то деструкторе на строке
auto cid(compose(id(),id()));.
Re: auto in argument list
От: D14  
Дата: 14.07.09 09:49
Оценка:
Господа, а это даже весело.

Вот такой код выполняется без ошибок. (Intel C++ + MSVC2008)
#include <functional>
#include <iostream>
#include <string>

typedef std::tr1::function<int(int)> inttoint;

inttoint id(){return [](int x) { return x; };}

int main()
{
    auto compose=[](const inttoint& f, const inttoint& g)
    {
        return [&](int x) { return f(g(x)); };
    };
    std::cout << compose(id(),id())(1234) << std::endl;
    return 0;
}

Но стоит поменять одну строчку на
return [=](int x) { return f(g(x)); };

Access violation.

Пойду матчасть покурю.
Re[5]: auto in argument list
От: jazzer Россия Skype: enerjazzer
Дата: 14.07.09 10:05
Оценка:
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, <Аноним>, Вы писали:


А>>А можно и так:

А>>
А>>#define foreach BOOST_FOREACH
А>>

А>>
CC>Не, так нельзя
CC>Придется буст подрубать
CC>а это сильно больше одной строки -> минус скорости компиляции.
CC>тем более бустовый форыч сильно громоздкий.

Зато бустовый форыч работает на С++03.
И, естественно, он будет переписан на auto для компиляторов, в которых оно уже есть.
Так что код c буст.форычем будет работать на любом компиляторе, и юзать по максимуму то, что есть.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: auto in argument list
От: CreatorCray  
Дата: 14.07.09 11:48
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Зато бустовый форыч работает на С++03.

для С++03 немного геморройнее

#define foreach(decl,it,cont) if (false) {} else for (decl::iterator it = (cont).begin(), c_foreach_end_##it = (cont).end();it != c_foreach_end_##it;++it)
#define c_foreach(decl,it,cont) if (false) {} else for (decl::const_iterator it = (cont).begin(), c_foreach_end_##it = (cont).end();it != c_foreach_end_##it;++it)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.