Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Общие вопросы > Текущий Стандарт С++ и перспективы его развития


Автор: archimed7592 11.06.07, 23:42
К октябрю 2007 года комитет запланировал публикацию законченного черновика стандарта C++09(который будет доступен публике для рассмотрения и критики).
В октябре 2008 комитет внесёт окончательные коррективы в стандарт и, наконец, на 2009 год запланированна публикация нового стандарта "ISO/IEC 14883(2009): Programming Language C++".

Надеюсь, не мне одному интересно, что же ожидает нас в новом С++. Потому, проштудировав документы, доступные обычным смертным на сайте open-std.org, я сделал маленький обзорчик ожидаемых вкусностей, которые готовит нам новый стандарт.

Итак, в кратце, крупные нововведения следующие:
  • rvalue references
  • template aliases
  • variadic templates
  • concepts
  • unicode characters/strings
  • initializer lists

Примечание: имеется так же обзор того, чего НЕ будет в С++09. Новый стандарт C++: C++09 (сообщение #1602819)



Rvalue References
Появились т.н. ссылки на rvalue. Сначала поясню зачем их вообще изобрели. Исходных проблемы было две: forwarding problem и move semantics.


Forwarding problem
Эта проблема заключается в том, что текущий стандарт, для заданного выражения E(a1,a2,...,aN), которое зависит от параметров a1,a2,...,aN, не позволяет написать такую ф-цию(или функтор), которая будет эквивалентна этому выражению.

Проблема актуальна для разного рода шаблонных обёрток, фабрик, обобщённых функторов и т.п.

За идеал перенаправляющей ф-ции(perfect fowarding function) f(a1,a2,...,aN), которая вызывает g(a1,a2,...,aN) взяли следующие критерии:
  • Для всех наборов a1,a2,...,aN, для которых запись g(a1,a2,...,aN) корректна(well-formed), запись f(a1,a2,...,aN) должна быть так же корректна.
  • Для всех наборов a1,a2,...,aN, для которых запись g(a1,a2,...,aN) некорректна(ill-formed), запись f(a1,a2,...,aN) должна быть так же некорректна.
  • Количество работы, которую придётся проделать для реализации такой идеально-перенаправляющей ф-ции f должно не более чем линейно зависеть от N.

Вот простейший пример:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T1, class T2, class T3>
    void f(T1 &a1, T2 &a2, T3 &a3)
    {
        g(a1, a2, a3);
    }
Всё бы хорошо, но нельзя сделать вызов f(1, 2, 3).

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T1, class T2, class T3>
    void f(const T1 &a1, const T2 &a2, const T3 &a3)
    {
        g(a1, a2, a3);
    }
Можно сделать вызов f(1, 2, 3), но, если g хотя бы для одного из параметров берёт неконстантную ссылку, то - облом.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class A1> void f(A1 & a1)
    {
        g(a1);
    }
     
    template<class A1> void f(A1 const & a1)
    {
        g(a1);
    }
Для перегруженного варианта всё отлично, кроме 3-го пункта, а именно, при росте числа параметров N, кол-во ф-ций, которые придётся написать, равное 2N, будет расти совсем нелинейно.


Короче говоря, текущий стандарт решить эту проблему не позволяет.


Move semantics
С++ - язык, построенный на семантике копирования(copy semantics). Что такое семантика перемещения(move semantics)? Хороший пример - std::auto_ptr. Его конструктор копирования берёт неконстантную ссылку и перемещает хранимую в исходном объекте сущность в новый объект(тем самым избегая глубокого копирования). Но, несмотря на то, что конструктор копирования auto_ptr берёт неконстантную ссылку, его суть не в том, чтобы изменить объект, а в том, чтобы переместить к себе его содержимое. Так же, семантика перемещения не помешала бы строкам. Вообразим, что строки у нас без подсчёта ссылок. Теперь вообразим, сколько ресурсов будет затрачено на вычисление такого выражения:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    string s = string("123")+"234"+"567"+"678"+"789";

будет создано как минимум 5 временных объектов и потом ещё произойдёт глубокое копирование результирующей строки в s(если нету подсчёта ссылок).
А теперь, вообразим, как было бы прекрасно, если бы конструктор копирования умел бы отличать какой объект ему подсунули - временный или нет. Действительно, о временных объектах можно не волноваться и с чистой совестью "забирать" у них выделеный ими буфер, без необходимости глубокого копирования.
К слову, эту проблему можно решить текущими возможностями языка, но очень уж некрасиво...

Что же нам предлагает новый стандарт?
А предлагает он следующее: ввести новый тип ссылок - rvalue reference.
Синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    T t; // lvalue
    T &rt = t; // lvalue reference
    T &&rrt = t; // rvalue reference
     
    // правила сворачивания ссылок
    T cv1 &  cv2 &  <=> T cv12 &
    T cv1 &  cv2 && <=> T cv12 &
    T cv1 && cv2 &  <=> T cv12 &
    T cv1 && cv2 && <=> T cv12 &&

Любая именованная rvalue-ссылка трактуется как lvalue.
Любая неименованная rvalue-ссылка трактуется как rvalue.
Т.к. теперь появилась возможность различать тип выражения(lvalue или rvalue), появилась и возможность кастовать lvalue к rvalue: static_cast<T &&>(lval) будет трактоваться как rvalue.
Возвращаемое значение из ф-ции интерпретируется как rvalue т. е.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    return val; <=> return static_cast<ret_T &&>(val);

Т.о. можно избежать глубокого копирования и ограничиться только лишь перемещением из возвращающей ф-ции в вызвавшую(при наличии соответствующего конструктора).

Forwarding problem решается теперь следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void g(long & a1)
    {
        ++a1;
    }
     
    template<class A1> void f(A1 && a1)
    {
        g(static_cast<A1 &&>(a1));
    }
     
    int i = 5;
    g(i); //fails - int & to long & - запрещённый каст ещё в C++03
    f(i); //fails
    // A1 выводится(deduced) как int &
    // A1 && <=> int & && <=> int &
    // a1 - lvalue-reference of int
    // static_cast<int &>(a1) - lvalue-reference of int
    // f(i) не компилируется по тем же причинам, что и не компилируется g(i)
     
     
     
    g(1L); // fails - rvalue of long to long & - запрещённый каст ещё в C++03
    f(1L); // fails
    // A1 выводится как long
    // a1 - lvalue of long(named rvalue-reference <=> lvalue)
    // static_cast<long &&>(a1) - rvalue of long(lvalue to rvalue cast)
    // f(1L) не компилируется т.к. rvalue to non-const lvalue-reference - запрещённый каст ещё в C++03
     
     
    long L;
    g(L); // ok
    f(L); // ok
    // A1 выводится как long &
    // A1 && <=> long & && <=> long &
    // a1 - lvalue-reference of long
    // static_cast<long &>(a1) - lvalue-reference of long
    // f(L) компилируется(как и должна)



Move semantics обеспечивается следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class string
    {
    public:
        string(const string &); // copy constructor
        string(string &&); // move constructor
        string &operator +=(string &); // copy semantics operator +=
        string &&operator +=(string &&); // move semantics opertor +=
    };
     
    string &&operator +(string &&s1, string &&s2)
    {
        return s1 += s2;
        // т.к. s1 - временный объект, мы не создаём новую строку, мы модифицируем существующую
    }


В случаях, когда необходимо вызвать конструктор перемещения для объекта, который не является rvalue, можно сделать каст, запросив необходимое поведение следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    string s1("abc");
    string s2 = s1; // construct s2 as s1 copy
    string s3 = static_cast<string &&>(s1); // move from s1 to s2



Лично я эту фичу считаю очень полезной. Особенно, учитывая появившуюся возможность отличать временные объекты от невременных таким образом увеличив производительность в разы, избавившись от лишних операций копирования.




Template aliases


Думаю все оценят эту фичу.
Проблем, побудивших ввести алиасы две.
Первая заключается в том, что очень часто появляется нужда в "шаблонном typedef'е". Wrokaround'ом этой проблемы как правило является следующая конструкция:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T >
    struct MyVector
    {
        typedef std::vector< T, MyAllocator< T > > type;
    };
     
    MyVector< int >::type vec; // не очень красивая запись

Вторая же проблема выражается в том, что при использовании вышеобозначенного workaround'а перестаёт работать вывод шаблонных параметров.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T >
    void f(std::vector< T > &)
    { }
     
    template < class T >
    void f2(typename MyVector< T >::type &)
    { }
     
    std::vector< int > v;
    MyVector< int >::type v2;
    f(v); // ok
    f2(v2); // ill-formed

Алиасы позволяют решить обе проблемы. Алиасы представляют из себя объявления. Они не определяют новых типов.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T >
    using MyVector = std::vector< T, MyAllocator< T > >;
     
    using MyFloat = float;
     
    void f1(float) { }   // ok
    void f1(MyFloat) { } // ill-formed - redefinition

Шаблонные алиасы нельзя специализировать, но, можно специализировать тип синонимом которого является алиас.






Variadic templates


Это нововведение избавляет программиста, реализующего библиотеку списков типов или библиотеку, подобную boost::bind от реализации всех возможных вариаций типа
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class R >
    unspecified bind(...);
     
    template < class R, class A1 >
    unspecified bind(...);
     
    template < class R, class A1, class A2 >
    unspecified bind(...);
     
    // ...
     
    template < class R, class A1, class A2, ..., class AN >
    unspecified bind(...);

И позволяет сделать шаблон, принимающий переменное количество шаблонных параметров:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class R, class... Args> // здесь троеточие - это синтаксический элемент
    R f(Args... args)
    {
        return g(args...); // вызываем g, передавая ей все аргументы.
    }

Как к типам(Args), так и к экземплярам этих типов(args) можно применять разные операторы.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class R, class... Args >
    R fwd_by_pointer(Args &... args) // <=> R fwd_by_pointer(Arg1 & arg1, Arg2 & arg2, ..., ArgN & argN)
    {
        return g(&args...); // <=> return g(&arg1, &arg2, ..., &argN);
    }

Количество типов в наборе можно узнать с помощью нового оператора sizeof...:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class... Types >
    struct S
    {
        enum { result = sizeof...(Types) };
    };

Языковых средств для вытягивания типов из набора(Args) нету, но, это не очень сложно делается руками(и уже сделано в стандартной библиотеке - std::tuple и иже с ним). Языковых средств для вытягивания значения из набора(args) вроде как нету, но, опять же, руками это делается несложно - std::tuple тому пример.
В документах встречалось упоминание, что значение можно вытянуть как из массива(args[3], к примеру), но в грамматике я такого упоминания не нашел.





Concepts


Ну это вообще просто сказка :)
Пару слов про сами концепции. Любой, кто использовал обобщённые алгоритмы/структуры данных сталкивался с разного рода требованиями к обобщаемому типу. Наиболее распространенные: DefaultConstructible, CopyConstructible, LessThanComparable. Также, концепциями являются InputIterator, OutputIterator, ForwardIterator, etc. Короче говоря, это требования к обобщаемому типу, невыполнение которых может привести к ошибке инстанцирования шаблона. На данный момент такие требования повсеместно встречаются в документации(IS, boost docs, etc). Теперь эти требования можно будет выражать в коде.

Какие проблемы решат концепции?
Ну, во-первых, это, конечно то, что теперь, тип будет сначала проверятся на соответствие концепции и только после удачного завершения этой проверки, произойдёт попытка инстанцирования шаблона. Т.о. если тип не LessThanComparable, то при попытке использовать его в контейнере map(к примеру) не придётся втыкать на километры выданных компилятором ошибок. Ошибка будет выглядеть примерно так: "тип T не является LessThanComparable", что, замечу, большой плюс. Все, кто использовал boost::bind/lambda::bind оценят :)

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

В-третьих, писать обобщённый код станет проще. С концепциями можно делать что только душе угодно. К примеру, если тип vector не соответствует концепции Stack(у него нету ф-ций push/pop), но, принципиально его можно использовать как тип соответствующий этой концепции(можно использовать ф-ции push_back/pop_back), то, без потери для общности, можно написать что-то вроде адаптера(concept_map), который будет приспосабливать данный тип к заданной концепции. Концепциями можно защитить не весь класс, а только некоторые его методы. Также, можно разработать несколько версий алгоритма эффективных для той или иной концепции и перегрузить его так, что будет выбран наиболее подходящий алгоритм.

Синтаксис концепций интуитивно понятен и поясню я только некоторые моменты.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // вот так определяются концепции
    auto concept LessThanComparable< typename T >
    {
        bool operator<(T, T);
    };
     
    template< LessThanComparable T > // вот так предъявляются требования к типу T
    const T& min(const T& x, const T& y)
    {
        return x < y ? x : y;
    }
     
    template < typename T >
        where LessThanComparable< T > // или можно предъявить требования так
    const T& min(const T& x, const T& y)
    {
        return x < y? x : y;
    }
     
    // пример более объёмной концепции
    auto concept Regular < typename T >
    {
        T::T(); // default constructor
        T::T(const T&); // copy constructor
        T::~T(); // destructor
        T& operator=(T&, const T&); // copy assignment
        bool operator==(T, T); // equality comparison
        bool operator!=(T, T); // inequality comparison
        void swap(T&, T&); // swap
    };
     
    // ещё пример
    auto concept Convertible <typename T, typename U>
    {
        operator U(T);
    };
     
     
    template < typename U, typename T >
        where Convertible< T, U > // концепции можно использовать для задания некоторых взаимоотношений между несколькими типами
    U convert(const T& t)
    {
        return t;
    }
     
     
    // итератор
    auto concept InputIterator < typename Iter >
    {
    typename value_type; // ассоциированные типы
    typename reference;
    typename pointer;
    typename difference_type;
    where Regular<Iter>; // вложенные требования
    where Convertible<reference_type, value_type>;
    reference operator*(Iter); // dereference
    Iter& operator++(Iter&); // pre-increment
    Iter operator++(Iter&, int); // post-increment
    // ...
    };
     
    template <InputIterator Iter>
        where Regular<Iter::value_type>
    Iter find(Iter first, Iter last, const Iter::value_type& value)
    {
        while (first != last && *first != value)
            ++first;
        return first;
    }
     
     
    auto concept BinaryFunction<typename F, typename T1, typename T2>
    {
        typename result_type;
        result_type operator()(F&, T1, T2);
    };
     
    auto concept BinaryPredicate<typename F, typename T1, typename T2>
        : BinaryFunction<F, T1, T2> // пример "наследования" концепций
    {
        where Convertible<result_type, bool>;
    };
     
     
    // уточнение для char * у которого нету ассоциированных с ним типов
    // аналог traits, только намного более мощный(см. далее)
    concept_map InputIterator<char*>
    {
        typedef char value_type ;
        typedef char& reference ;
        typedef char* pointer ;
        typedef std:: ptrdiff_t difference_type ;
    };
     
     
    concept Stack<typename X>
    {
        typename value_type;
        void push(X&, value type);
        void pop(X&);
        value type top(const X&);
        bool empty(const X&);
    };
     
    // пример адаптации вектора к концепции Stack
    template<typename T>
    concept_map Stack< std::vector<T> >
    {
        typedef T value_type;
        void push(std:: vector<T>& v, T x) { v. push_back(x); }
        void pop(std:: vector<T>& v) { v. pop_back(); }
        T top(const std:: vector<T>& v) { return v.back(); }
        bool empty(const std::vector<T>& v) { return v.empty(); }
    };
     
     
    // концепция, которой удовлетворяет вектор(и не только)
    concept BackInsertionSequence<typename X>
    {
        typename value_type = X::value type;
        void X::push_back(value type);
        void X::pop_back();
        value_type& X::back();
        const value_type& X::back() const;
        bool X::empty() const;
    };
     
     
    // пример, как можно адаптировать любой тип, удовлетворяющий концепции C1, к концепции C2.
    // другими словами, как адаптировать одну концепцию к другой
    template<BackInsertionSequence X>
    concept_map Stack<X>
    {
        typedef X::value_type value_type;
        void push(X& x, value_type value ) { x. push_back(value); }
        void pop(X& x) { x. pop_back(); }
        T top(const X& x) { return x.back(); }
        bool empty(const X& x) { return x.empty(); }
    };
     
     
    // пример перегрузки на основе концепций - будет выбрана самая "специфичная" форма
    //т.е. для BidirectionalIterator будет выбран второй вариант, несмотря на то, что удовлетворяет и первый(InputIterator)
    template<InputIterator Iter>
    void advance(Iter& x, Iter::difference type n)
    {
        while (n > 0) { ++x; --n; }
    }
    template<BidirectionalIterator Iter>
    void advance(Iter& x, Iter::difference type n)
    {
        if (n > 0) while (n > 0) { ++x; --n; }
        else while (n < 0) { --x; ++n; }
    }
    template<RandomAccessIterator Iter>
    void advance(Iter& x, Iter::difference type n)
    {
        x += n;
    }
     
    // пример разных реализаций контейнера для разных хранимых типов данных
    template<EqualityComparable T>
    class dictionary
    {
        // slow, linked-list implementation
    };
    template<LessThanComparable T>
        where !Hashable<T>
    class dictionary<T>
    {
        // balanced binary tree implementation
    };
    template<Hashable T>
    class dictionary<T>
    {
        // hash table implementation
    };
     
     
    // пример, как можно обложить ограничениями не весь класс, а только некоторые ф-ции(причём разными ограничениями)
    template<typename T, typename U>
    struct pair
    {
        where DefaultConstructible<T> && DefaultConstructible<U>
        pair() : first(), second() { }
     
        where CopyConstructible<T> && CopyConstructible<U>
        pair(const T& t, const U& u) : first(t), second(u) { }
     
        where Destructible<T> && Destructible<U>
        ~pair() { }
     
        where Assignable<T> && Assignable<U>
        pair& operator=(const pair<T, U>& other)
        {
            first = other.first;
            second = other.second;
        }
     
        T first;
        U second;
    };
     
     
    // ещё пример, как помимо CopyConstructible, может понадобится DefaultConstructible
    // но вектор может ф-ционировать и без второго требования потому его(требование) относят только к отдельной ф-ции.
    template<CopyConstructible T>
    class vector
    {
    public:
        // обратите внимание, как одна ф-ция разделилась на две, дабы добавить контейнеру общности :)
     
        // vector(size t n, const T& value = T());
        
        vector(size t n, const T& value);
     
        where DefaultConstructible<T> vector(size t n);
    };

Ключевое слово where в последней версии вроде как решили заменить на слово requires.



Unicode characters/strings
Ну, собственно, ничего интересного, кроме самого факта: теперь в С++ оффициальная поддержка UTF-16(u"...") и UTF-32(U"..."). Ну а факт, я считаю, немаловажный и вполне достойный соответствующего внимания со стороны публики :)
Появились новые типы char16_t и char32_t.
Также, отдельно рассматривается добавление UTF-8(E"...").





Initializer lists


<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    X t1 = v; // "copy initialization" possibly copy construction
    X t2(v); // direct initialization
    X t3 = { v }; // initialize using initializer list   <<<=================
    X t4 = X(v); // make an X from v and copy it to t4

Достаточно обширное нововведение. Пока всех подробностей не выяснил, но, в двух словах постараюсь рассказать.
В языках типа C# практикуется такое:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    f(new char[] {'1', 'a', '-'});

В С++09 предполагается нечто подобное(только без new :)).
Теперь можно будет написать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector< int > v = { 1, 2, 3, 4, 5 };

Как написать класс, чтобы его можно было вот так инициализировать?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <initializer_list> // этот хэдер предоставляет класс std::initializer_list
     
    namespace std
    {
    template<class E> class initializer_list
    {
        // representation implementation defined
        // (probably two pointers or a pointer and a size)
        // implementation defined constructor
     
    public:
        // default copy construction and copy assignment
        // no default constructor
        // default trivial destructor
     
        constexpr int size() const; // number of elements
        const T* begin() const; // first element
        const T* end() const; // one-past-the-last element
    };
    }
     
    class A
    {
    public:
        A(std::initializer_list< char > a) { /* ... */ }
        // ...
    };
     
    class B
    {
    public:
        B(std::initializer_list< double > a) { /* ... */ }
        // ...
    };
     
    void f(const A &a); // #1
    void f(const B &b); // #2
     
    int main
    {
     
        A a1 = {1, 2, 3};
        A a2{2, 3, 4};
        A a3;
        a3 = A{3, 4, 5};
     
        f({1, 2., 3}); // ambiguity
        f(A{1, 2., 3}); // #1
        f(B{1, 2., 3}); // #2
        f({1., 2., 3.}); // #2
        f{'a', 'b', 'c'}; // #1
     
        return 0;
    }





Синтаксические мелочи



static_assert
Новое ключевое слово, позволяет во время компиляции сделать проверку и, в случае чего, сгенерить ошибку компиляции(текст ошибки можно указывать).
Наибольшее применение, имхо, будет иметь в шаблонах, хотя, с появлением концепций - сомнительно :).
Так же, возможно использование как замена старой доброй директивы #error.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename T>
    struct Check
    {
        static_assert(sizeof(int) <= sizeof(T), "not big enough");
    };




Расширенная функциональность sizeof
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct C
    {
       some_type m;
       // ...
    };
     
    const std::size_t sz = sizeof(C::m); // C++03 - error, C++09 - ok




Delegating Constructors
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // C++03 workaround
    class A
    {
        void Init(/* ... */) { /* ... */ }
    public:
        A()
        { Init(); };
        A(/* ... */)
        { Init(); /* ... */ }
    };
     
    // C++09 well-formed code
    class A
    {
    public:
        A()
        { /* initializations */ };
        A(/* ... */)
            : A() // <<==== delegating construction
        { /* other initializations */ }
    };




Inheriting Constructors
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct B1 {
      B1( int, int ) {}
    };
     
    struct B2 {
      B2( double, double ) {}
    };
     
    struct D1 : B1 {
      using B1::B1;  // impliclty declare D1( int a1, int a2 ) : B1(a1, a2) {}
      int x;
    };
     
    struct D2 : B2 {
      using B2::B2; // impliclty declare D2( double a1, double a2 ) : B2(a1, a2) {}
      B1 b;
    };




Deducing the type of variable from its initializer expression.
Достаточно интересная штука... настолько же, насколько и опасная, имхо...
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int foo();
    auto x1 = foo(); // x1 : int
    const auto& x2 = foo(); // x2 : const int&
    auto& x3 = foo(); // x3 : int&: error, cannot bind a reference to a temporary
    float& bar();
    auto y1 = bar(); // y1 : float
    const auto& y2 = bar(); // y2 : const float&
    auto& y3 = bar(); // y3 : float&
    A* fii();
    auto* z1 = fii(); // z1 : A*
    auto z2 = fii(); // z2 : A*
    auto* z3 = bar(); // error, bar does not return a pointer type
     
    // из очень полезных применений вижу следующее
    // особенно полезно при замене контейнера(-ов) на концептуально аналогичные, но по типизации разные
    std::map< std::string, std::map< std::string, std::set< std::vector< bool > > > > container;
    for (auto i1 = container.begin(), e1 = container.end(); i1 != e1; ++i1)
        for (auto i2 = i1->second.begin(), e2 = i1->second.end(); i2 != e2; ++i2)
            for (auto i3 = i2->second.begin(), e3 = i2->second.end(); i3 != e3; ++i3)
                for(auto i4 = i3->begin(), e4 = i3->end(); i4 != e4; ++i4)
                {
                    /* ... */
                }
     
     
     
    // ещё, появилась штука, ожидаемая под названием typeof.
    // в C++09 её назвали decltype
    decltype(container.begin()) i = container.begin();




Extended friend Declarations
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class C;
    typedef C Ct;
     
    class X1
    {
        friend C; // OK: class C is a friend
    };
    class X2
    {
        friend Ct; // OK: class C is a friend
    };
    class X3
    {
        friend class Ct; // C++09 - ok, C++03 - ill-formed
    };




Extern templates
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T >
    class MyVector { /* ... */ };
     
    template class MyVector< int >; // explicit instantination
     
    extern tempalte class MyVector< int >; // extern explicit instantination

сделано для того, чтобы диначическая библиотека могла сделать у себя explicit instantination, а клиент у себя extern explicit instantintaion



Right Angle Brackets
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector<std::set<int>> v; // C++03 - ill-formed, C++09 - well-formed




Range-based for-loop
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int array[5] =  { 1,2,3,4,5 };
    std::vector< int > vec = { 1, 2, 3, 4, 5 }; // так инициализировать нельзя, но мы это опустим :)
    for ( auto& x : array )
        x *= 2;
     
    for ( float x : vec )
        std::cout << x << std::endl;




C99 Compatibility: __func__
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace N { void f(); }
    void N::f() { }                 // __func__ is "f"
     
    struct S
    {
        S() : s(__func__) { }         // ok, s points to "S"
        ~S() { }                      // __func__ is "~S"
        operator int() { }            // __func__ is "conversion operator"
        template<class T> int g();
        const char *s;
    };
    S operator +(S,S) { }           // __func__ is "operator+"
    template<> int S::g<int>() { }  // __func__ is "g"
     
    struct S
    {
        S() : s(__func__) { }            // ok
        const char *s;
    };
    void f(const char * s = __func__); // error: __func__ is undeclared




Generalized Constant Expressions
constexpr - новое ключевое слово.
Суть нововведения в том, что теперь, например, можно как размерность массива использовать результат, возвращенный ф-цией.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A
    {
        constexpr A(int i) : val(i) { }
        constexpr operator int() { return val; }
        constexpr operator long() { return 43; }
    private:
        int val;
    };
     
    template<int> struct X { };
    constexpr A a = 42;
    X<a> x; // OK: unique conversion to int
    int ary[a]; // error: ambiguous conversion




Explicit Conversion Operators
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class T { };
    class X
    {
    public:
        explicit operator T() const;
    };
     
    int main()
    {
        X x;
        
        // Direct initialization:
        T t4( x );
        
        // Copy initialization:
        T t8 = x; // error
     
        // Cast notation:
        T t12 = (T) x;
     
        // Static_cast:
        T t16 = static_cast<T>( x );
     
        // Function-style cast:
        T t20 = T( x );
        return 0;
    }




Raw String Literals
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char *s1 = "('(?:[^\\\\']|\\\\.)*'|\"(?:[^\\\\\"]|\\\\.)*\")|";
    char *s2 = R"[('(?:[^\\']|\\.)*'|"(?:[^\\"]|\\.)*")|]" // кто работал с regex на с++ - оценят :)
    // post: strcmp(s1, s2) == 0
     
     
    char *s3 =
    "<HTML>\n"
    "<HEAD>\n"
    "<TITLE>Auto-generated html formated source</TITLE>\n"
    "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=windows-1252\">\n"
    "</HEAD>\n"
    "<BODY LINK=\"#0000ff\" VLINK=\"#800080\" BGCOLOR=\"#ffffff\">\n"
    "<P> </P>\n"
    "<PRE>\n";
     
    char *s4 =
    R"[\
    <HTML>
    <HEAD>
    <TITLE>Auto-generated html formated source</TITLE>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
    </HEAD>
    <BODY LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff">
    <P> </P>
    <PRE>
    ]"
     
    // post: strcmp(s3, s4) == 0




A name for the null pointer: nullptr
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char* ch = nullptr; // ch has the null pointer value
    char* ch2 = 0; // ch2 has the null pointer value
    int n = nullptr; // error
    int n2 = 0; // n2 is zero
    if( ch == 0 ); // evaluates to true
    if( ch == nullptr ); // evaluates to true
    if( ch ); // evaluates to false
    if( n2 == 0 ); // evaluates to true
    if( n2 == nullptr ); // error
    if( nullptr ); // error, no conversion to bool
    if( nullptr == 0 ); // error
     
    // arithmetic
    nullptr = 0; // error, nullptr is not an lvalue
    nullptr + 2; // error




Alignment Support
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // новые ключевые слова: alignas, alignof
    const std::size_t align_of_int = alignof(int);
    T alignas(T) alignas(long) t1;
    T alignas(T) alignas(align_of_int) t2;




Prohibited access specifier
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template< typename T >
    struct owned_ptr
    {
    public:
        explicit owned_ptr( T * p ) : pt( p ) {}
        ~owned_ptr() { delete pt; }
     
        T * operator->() { return pt; }
        T const * operator->() const { return pt; }
     
    private:
        T * pt;
        void foo();
     
    prohibited:
        owned_ptr( owned_ptr const & );
        owned_ptr & operator=( owned_ptr const & );
    };
    template< typename T >
    void S< T >::foo()
    {
        new owned_ptr(*this); // compile-time error(не link-time)
    }




Explicit class and default definitions
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class A
    explicit
    {
    // no implicitly declared/defined special member functions(default ctor, copy ctor, copy assignment operator, destructor)
    };
     
    class B
    explicit
    {
    public:
        B() {default} // default ctor definition(compiler generated)
    };
     
    class I
    explicit
    {
    public:
        virtual ~I() {default}
    };




Defaulted and Deleted Functions
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct type
    {
        type() = default; // trivial
        virtual ~type() = default; // non-trivial because virtual
        type & operator =( const type & ); // declaration and....
    };
    inline // the inline definition keeps it trivial
    type & type::operator =( const type & ) = default;
     
    // --------------------------------------------------------------
     
    struct type
    {
        type( const type & ); // declaration and....
    };
    type::type() = default; // the non-inline makes it non-trivial
     
    // --------------------------------------------------------------
    struct type
    {
        type & operator =( const type & ) = delete;
        type( const type & ) = delete;
        type() = default;
    };
    // --------------------------------------------------------------
    struct type
    {
        void * operator new( std::size_t ) = delete;
    };
    // --------------------------------------------------------------
    struct type
    {
        ~type() = delete; // disable destructor
    };
    // --------------------------------------------------------------
    struct type
    {
        type( long long ); // can initialize with an long long
        type( long ) = delete; // but not anything less
    };
    extern void bar( type, long long ); // and the same for bad overloads
    void bar( type, long ) = delete; // of free functions
    // --------------------------------------------------------------
    struct type
    {
        type( long long );
        explicit type( long ) = delete;
    };
    extern void function( type );
    function( type( 42 ) ); // error 42 promotes to long
    function( 42 ); // okay type(long long); type(long) not considered



Pure implementation method declaration
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct Base
    {
        virtual void f1() = 0;
        virtual void f2() = 0;
    };
     
    struct S
        : public Base
    {
        virtual void f1() > 0;  // должно быть определение S::f1, иначе compile-time error
        virtual void f2() >= 0; // определение S::f2 может быть, а может и не быть :)
        virtual void f3() > 0; // compile-time error - нету объявления Base::f3.
        virtual void f4() >= 0; // compile-time error - нету объявления Base::f3.
    };




Strongly Typed Enums
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    enum class E { E1, E2, E3 = 100, E4 /* = 101 */ };
    void f( E e )
    {
        if( e >= 100 ) ; // error: no E to int conversion
    }
    int i = E::E2; // error: no E to int conversion
    // ------------------------------------------------------
    enum class E { E1, E2, E3 = 100, E4 /* = 101 */ };
    E e1 = E1; // error
    E e2 = E::E2; // ok
    // ------------------------------------------------------
    enum class E : unsigned long { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U };
    unsigned long ul = E::Ebig;








Формальные мелочи


Conditionally-Supported Behavior
Добавлен новый вид определяемого стандартом поведения.
Теперь, конструкции для которых поведение было неопределено(UB), считаются conditionally-supported и могут интерпретировать либо как implementation-defined, либо как ill-formed.



Замена некоторых UB на Diagnosable Errors
К примеру, теперь передача non-POD в элипсис приведёт к ошибке компиляции, а не к UB как в C++03.



Новая модель выполнения программы
В связи с добавлением оффициальной поддержки multithreading.
Убрали понятие sequence point.
Добавили понятие evaluation - набор выборок(чтение значения переменной) и side effects, которые происходят в ходе вычисления выражения.
Понятие sequence point заменили аж тремя понятиями sequencing constraints: sequenced before, unsequenced, indeterminately sequenced. Эти понятия - отношения между двумя evaluations A и B(A sequenced before B, A and B unsequenced, etc).
Теперь порядок вычисления операндов не unspecified. Теперь evaluations of operands unsequenced :)
В связи с отсутствием понятия sequence point вычисление операндов операторов "a && b", "a || b", "a ? b : c" и "a, b" примерно следующее: evaluation of a is sequenced before evaluation of b.



Облегчение ограничений на POD'ы
Ввели два новых понятия: trivial-class и standard-layout-class. POD - это класс, который является одновременно и trivial и standard-layout.
Теперь все гарантии, которые давал POD можно разделить на 2 части: первые даются для trivial типов, вторые для standard-layout.
В общем теперь большее кол-во типов будет поддаваться копированию посредством memcpy и т.п.



Перегрузка операторов
Рассматривается возможность перегрузки операторов
.
.*
static_cast<>
const_cast<>
dynamic_cast<>






Стандартная библиотека

Дополнение к этому пункту и/или более подробные описания фич можно увидеть здесь:
Новый стандарт C++. C++09 (сообщение #1601275)


cstdint из C99
Добавленна опциональная поддержка типов с размером точно соответствующим указанному.
int8_t, int16_t, int32_t, int64_t
uint8_t, uint16_t, uint32_t, uint64_t

Обязательная поддержка для типов с размером не меньшим указанного.
int_least8_t, int_least16_t, etc.
uint_least8_t, etc.

И обязательная поддержка типов с размером точно соответствующим указанному, но, возможно, более быстрых, чем их least-эквиваленты.
int_fast8_t, etc.
uint_fast8_t, etc.



Контейнеры
Sequence container: std::array - см. ниже "Перешло из boost".
Unordered associative containers:
unordered_map, unordered_multimap,
unordered_set, unordered_multiset
Вполне ожидаемые контейнеры работающие по принципу хэширования, ранее известные под названием hash_set/map в "вольных" реализациях STLport, MS VC-8.0.



В связи с введением rvalue-reference и move semantics
Во-первых, повсеместное добавление/переведение вышеобозначенной семантики для повышения производительности(там, где это возможно).
Добавлены ф-ции помошники move и forward, означающие не что иное, как прямое предназначение rvalue-ссылок. Первая вынуждает использовать семантику перемещения даже если операнд - lvalue(-reference). Вторая осуществляет необходимые телодвижения для достижения perfect forwarding :)

Добавлен move_iterator< class Iter >, который работает точно также, как Iter, за исключением того, что его dereferencing оператор принуждает использовать семантику перемещения.



В связи с введением constexpr
Много где встречаются эти константные ф-ции(результат которых можно использовать даже для определения статического массива).
К примеру numeric_limits. Теперь его ф-ции min/max отвечают соответствующим требованиям.



Перешло из boost
std::tuple
Тож самое, что и boost::tuple, за одним отличием - переведён на синтаксис variadic templates.

std::bind
Тож самое, что и boost::bind, за одним отличием - переведён на синтаксис variadic templates.

std::array(sequence container)
Тож самое, что и boost::array. Вроде где-то упоминалось, что собираются сделать его N-мерным(в отличие от 1-мерного boost::array).

std::regex
См. boost::regex


Многопоточность
Ничего не могу сказать более определённого, чем то, что в новом С++ будет поддержка многопоточности и будет предоставленно API, совместимое с posix pthreads. Также, возможность выполнения атомарных операций(необходимо для синхронизации - реализации спин-локов)


P.S. Обсуждение упомянутых фич, а также, изложение информации о неупомянутых фичах очень даже приветствуется :wub:



remark: Добавлена ссылка на пост с продолжением: Новый стандарт C++. C++09 (сообщение #1601275)(стандартная библиотека)
remark: Добавлена ссылка на пост с продолжением: Новый стандарт C++: C++09 (сообщение #1602819)(чего не будет в С++09)
remark: Добавлена ссылка на пост с продолжением: TR1. Technical Report on C++ Library Extensions.
remark: Добавлена ссылка на пост с продолжением: Trip Report: February/March 2008 ISO C++ Standards Meeting

Автор: psx 12.06.07, 04:03
Целая статья - огромная работа! :lol: Молодец.
Щас буду вникать. Спасибо за перевод. 8-)

Автор: prografix 12.06.07, 08:42
С одной стороны эти изменения полезны, с другой усложняют и без того непростой язык. Отсюда следует, что должен появиться более простой язык, который станет самым популярным. Это не Java и не C#. Что касается описанных изменений, мне больше всего понравились Delegating Constructors.

Автор: Hryak 12.06.07, 09:14
Цитата prografix @
С одной стороны эти изменения полезны, с другой усложняют и без того непростой язык.

Чуешь зависимость: "Язык усложняется - его использование упрощается"?

Цитата
Отсюда следует, что должен появиться более простой язык, который станет самым популярным.

Silver bullshitet ?

Автор: archimed7592 12.06.07, 10:13
prografix, имхо здесь из усложнений только rvalue-references и то из-за того, что мозг ещё не освоился со всеми ньансами и не совсем понятно чего когда будет происходить... Но это только вопрос времени и мозг освоится так же быстро, как это было когда "появились" lvalue-references(в Си их же не было)... Всё остальное только упрощает код. Взять те же variadic templates. Если сейчас, я как огня боюсь залезать в бустовые хэдеры и пытаться одуплить реализацию bind, то, потом(с введением соответствующей фичи) - это будет так же просто, как одуплить реализацию вектора. В proposal'е была даже "примерная" реализация bind и, как ни странно, я всё понял :)

Цитата Hryak @
Silver bullshitet ?
эт че?

Добавлено
psx, да ты не торопись - разберись для начала с текущей реализацией языка ;)

Автор: mo3r 12.06.07, 11:18
Кстати, есть небольшая презенташка о состоянии готовящегося стандарта. Там описаны многие новые фичи языка.

Добавлено
Еще также подумывают про введение сборки мусора и облегчение создания динамически загружаемых модулей.

Автор: archimed7592 12.06.07, 11:32
mo3r, сборка мусора будет, но ничего, кроме самого факта я к сожалению не нашёл.
Модулей в C++09 не будет. Скорее всего сделают отдельным TR. А может и до следующего стандарта отложат.

Автор: Xenon_Sk 12.06.07, 11:59
archimed7592 а чего, boost стандартом так и не станет пока?

Автор: Gunnar 12.06.07, 12:45
archimed7592, Спасибо за статью! Очень понравилось.

Только вот не понял две вещи: :wall: :wall:

1. Raw String Literals
2. Prohibited access specifier

Обьясните поподробнее плз...

Добавлено
Ув. Модераторы, Может прибьете к потолку?

Автор: archimed7592 12.06.07, 12:52
Цитата Xenon_Sk @
archimed7592 а чего, boost стандартом так и не станет пока?

Весь - нет.
Вещи, которые хорошо продуманы и проверены временем включаются в стандартную библиотеку(см. пункт "Перешло из boost").

Добавлено
Цитата Gunnar @
1. Raw String Literals
К примеру работаешь ты с регулярными выражениями.
Вот вполне себе простенькая регулярка:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    \s+(\w+)\s+=\"((?:[^\"\\]|\\\"|\\n|\\t|...))*\"

в с++03 её придётся записать так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char *rx = "\\s+(\\w+)\\s+=\\\"((?:[^\\\"\\\\]|\\\\\\\"|\\\\n|\\\\t|...))*\\\"";

в с++09 можно будет записать так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char *rx = R"[\s+(\w+)\s+=\"((?:[^\"\\]|\\\"|\\n|\\t|...))*\"]";


Добавлено
Цитата Gunnar @
2. Prohibited access specifier

к примеру, все классы, расчитанные на динамическое использование запрещают копирование своих экземпляров
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class I
    {
    private: // запрещаем
        I(const I &);
        I& operator =(const I &);
    public:
        // ...
        void foo(const I &);
    };
     
     
    void I::foo(const I &a)
    {
        I b = a; // но запрет работает только для ф-ций не членов и не друзей.
        // здесь линкер ругнётся
        // и, не дай Б-г, кто-нибудь(ваш коллега, к примеру) додумается реализовать конструктор копирования - тогда не спасёт даже линкер
    }

В С++09 добавили такой спецификатор доступа, который делает запрет даже ф-циям членам.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class I
    {
    prohibited: // запрещаем
        I(const I &);
        I& operator =(const I &);
    public:
        // ...
        void foo(const I &);
    };
     
     
    void I::foo(const I &a)
    {
        I b = a; // запрет работает даже для ф-ций членов - compile-time error
    }

Автор: Gunnar 12.06.07, 13:12
archimed7592, все понял... И как я сам не допер? :blink: Все ж так просто.

Да новые возможности впечатляют. Не все еще вкурил окончательно, но это вопрос времени.



Но вот сэтим они конечно отожгли. Паскалюгой попахивает (или бейсиком??) :whistle:

Цитата archimed7592 @
Range-based for-loop

int array[5] = { 1,2,3,4,5 };
std::vector< int > vec = { 1, 2, 3, 4, 5 }; // так инициализировать нельзя, но мы это опустим :)
for ( auto& x : array )
x *= 2;

for ( float x : vec )
std::cout << x << std::endl;


Ну и сборщик мусора на мой взгляд - лишний. Был один язык лишенный этого греха, и тот сдался.

Автор: archimed7592 12.06.07, 13:21
Цитата Gunnar @
Паскалюгой попахивает (или бейсиком??) :whistle:
foreach - очень полезная фича. На данный момент либо используется std::for_each в связке с boost::lambda, либо кривоватый BOOST_FOREACH. Если это так часто используется, то почему бы не включить в стандарт поддержку на уровне языка?


Цитата Gunnar @
Ну и сборщик мусора на мой взгляд - лишний. Был один язык лишенный этого греха, и тот сдался.

Нет. Сборщик мусора будет исключительно опциональной фичей. Т.е. по умолчанию программа не будет знать ни о каком сборщике, а для того, чтобы пользоваться им придётся делать некоторые телодвижения. Скажу лишь, что в Symantec не дураки сидят(а именно они и занимаются добавлением GC в стандарт) и судя по их презенташкам(да и по логике вообще) сборка мусора должна только увеличить производительность в некоторого рода приложениях.

Автор: Xenon_Sk 12.06.07, 13:23
archimed7592 а где презентации поглядеть можно?

Автор: archimed7592 12.06.07, 13:27
Xenon_Sk,
Programmer Directed GC for C++
Transparent Garbage Collection for C++

Сейчас наткнулся на ещё кое-какие документы про GC, может попозже обзорчик GC напишу.

Автор: Unreal Man 12.06.07, 13:56
Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами :D А то глядишь – к великолепной поддержке template export ещё много чего добавится :lol:

Цитата
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    string s3 = static_cast<string &&>(s1); // move from s1 to s2

Я на данный момент реализую это примерно так:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A
    {
        typedef const std::nothrow_t &quick_move;
        // ...
        A(const A &); // copy-constructor
        A(A &, quick_move); // move-constructor
        A &lvalue() { return (*this); }
    };
     
    A GetA();
     
    void f()
    {
        A a1(/* ... */);
        A a2 = a1; // construct a2 as a1 copy
        A a3(a1, std::nothrow); // move from a1 to a3
        A a4(GetA().lvalue(), std::nothrow); // move from temporary to a4
    }

Раньше я создавал move-конструкторы с передачей указателя, но Yak уговорил меня этого не делать :-)

Цитата archimed7592 @
К примеру, теперь передача non-POD в элипсис приведёт к ошибке компиляции, а не к UB как в C++03.

Я вот только одной вещи пока не могу понять. Сейчас можно обернуть такой вызов в sizeof, и тогда никакого undefined behavior нет. Но будет ли такое работать в компиляторах с поддержкой C++09?

Цитата archimed7592 @
Перегрузка операторов
Рассматривается возможность перегрузки операторов
.
.*
static_cast<>
const_cast<>
dynamic_cast<>

Лучше б они для результата встроенного оператора –>* тип ввели.

Автор: archimed7592 12.06.07, 14:13
Цитата Unreal Man @
Сейчас можно обернуть такой вызов в sizeof, и тогда никакого undefined behavior нет.
Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру) так, чтобы это не повлекло UB. Приведи пример.


Цитата Unreal Man @
Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами :D А то глядишь – к великолепной поддержке template export ещё много чего добавится :lol:
С export template связаны некоторые проблемы реализации. Что же касается выше обозначенных фич - никаких проблем при реализации возникнуть не должно. К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. расширение vs-8.0 для поддержки template aliases и т.д.


Цитата Unreal Man @
Лучше б они для результата встроенного оператора –>* тип ввели.
сам то понимаешь, что это не совсем разумное решение будет?



Цитата Unreal Man @
Я на данный момент реализую это примерно так:
в изначальном документе, предлагающем move semantics было озвучено, что вроде как реализовать это можно и без rvalue-references чисто библиотечным путём:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      template <class T>
      class move_t
      {
        const T& t;
      public:
        move_t(const T& a) : t(a) {}
        operator T&(){ return t; /* тут видимо забыли const_cast, но я привожу дословно :) */ }
      };
     
    struct A
    {
        A(const A &); // copy ctor
        A(move_t<A>); // move ctor
    };
Не знаю, насколько это всё будет работать, но, в первом приближение - вполне себе будет работать :)
И тем не менее, поддержка на уровне языка мне нравится больше :)

Автор: mo3r 12.06.07, 14:29
Цитата archimed7592 @
Модулей в C++09 не будет. Скорее всего сделают отдельным TR. А может и до следующего стандарта отложат.

Похоже, что да... И так фич новых много.
Цитата Gunnar @
Ну и сборщик мусора на мой взгляд - лишний. Был один язык лишенный этого греха, и тот сдался.

Сборщик мусора полезен :) А проблема сборщиков во многих языков в том, что он неотключаем и некоторые вещи (типа RAII) с ним несовместимы. Здесь же планируется опциональный (т.е., указывается, к чему его надо применять, а к чему — нет). Поэтому комбинируются лучшие стороны — если нужен GC, он просто включается, а если не нужен, то он не мешает.
Цитата Unreal Man @
Ага, молитесь ещё, чтоб всё это поддерживалось новыми компиляторами :D А то глядишь – к великолепной поддержке template export ещё много чего добавится :lol:

Цитата archimed7592 @
К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts.

В g++ (версии 4.3 и в CVS HEAD) (и comeau) уже поддерживается часть новых фишек. Обещают добавлять туда поддержку фич по мере продвижения процесса голосования по ним. Так что к 2009 году наверняка будет по крайней мере два компилятора, обладающих хорошей поддержкой. msvc тоже наверняка будет поддерживать.

Автор: Unreal Man 12.06.07, 14:36
Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if (см. digitalmars.D.learn - static assert / static if)

Автор: archimed7592 12.06.07, 14:43
Цитата mo3r @
Похоже, что да... И так фич новых много.

Точно тебе говорю :). Со слов Саттера(да и комитета в общем) в С++09 этого не будет.

Цитата Unreal Man @
Кстати, по части шаблонов в C++ нередко не хватает чего-то вроде static if
во-первых, есть #if #else #endif, во-вторых, озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions"

Автор: Unreal Man 12.06.07, 14:46
Цитата archimed7592 @
Не совсем понял, как sizeof может помочь в передаче не-POD'а в элипсис(в printf, к примеру)

Не, тут другое дело. Иногда (у меня так почти всегда) эллипсис применяется для игр с перегрузкой функций, где результат перегрузки становится извествен благодаря sizeof (то, что внутри sizeof, не вычисляется в run-time). Пример можешь посмотреть здесь. Вот будет ли такое работать согласно новому стандарту?

Цитата archimed7592 @
сам то понимаешь, что это не совсем разумное решение будет?

Это почему же?

Добавлено
Цитата archimed7592 @
во-первых, есть #if #else #endif

Ну, эт совсем не то. Препроцессор тем и плох, что он препроцессор :) С шаблонами его не поюзаешь.

Цитата archimed7592 @
озвученная в указанной тобой статье проблема решается с помощью описанных в первом посте "Generalized Constant Expressions"

Покажи, каким образом.

Добавлено
Проблема с выбором у меня часто такая: нужно в зависимости от некоторого условия выбрать их двух или более шаблонных классов один в качестве typedef-а некоего типа, причём инстанцироваться должен только выбранный тип. Реализация такого выбора в C++ – геморрой редкостный.

Автор: archimed7592 12.06.07, 15:04
Цитата Unreal Man @
Не, тут другое дело.
Ну, раз другое дело... то и разговор другой и о другом :)

Цитата Unreal Man @
Вот будет ли такое работать согласно новому стандарту?
Будет. Почти всё, что работало до этого работать будет.
По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис.


Цитата Unreal Man @
Это почему же?
Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней. И опять же, зачем? Кому и для чего это нужно? В стандарт включают вещи, которые кому-то и зачем-то нужны.
И, в конце концов, для этого есть bind или mem_fn. Считай, что результат, возвращённый mem_fn является тем самым типом :tong:


Цитата Unreal Man @
Покажи, каким образом.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    constexpr int fact(int n)
    {
        if (n > 0)
            return fact(n - 1);
        else
            return 1;
    }
     
    double array[fact(5)]; // C++09 well-formed


Добавлено
Цитата Unreal Man @
Проблема с выбором у меня часто такая: нужно в зависимости от некоторого условия выбрать их двух или более шаблонных классов один в качестве typedef-а некоего типа, причём инстанцироваться должен только выбранный тип. Реализация такого выбора в C++ – геморрой редкостный.
эээ... либо я чего-то не понял, либо:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < bool Condition, class TrueType, class FalseType >
    struct select;
     
    template < class TrueType, class FalseType >
    struct select< true, TrueType, FalseType > { typedef TrueType type; };
     
    template < class TrueType, class FalseType >
    struct select< false, TrueType, FalseType > { typedef FalseType type; };
     
    template < int N >
    struct A
    {
        typedef typename select< (N > 0), vector< bool >, bitset< 256 > >::type container_t;
        // ...
    };


Добавлено
Прочитал все доступные на сайте комитета документы по GC. Пока толком не понял как коллектор будет реализовываться. Чего-то они там перемудрили со "сканированием памяти на предмет поиска указателей". Нафик сканировать массив char * и искать в нём указатели? :unsure:

Автор: trainer 13.06.07, 04:28
Цитата Gunnar @
Паскалюгой попахивает (или бейсиком??)
Это явно под влиянием Java. Там это выглядит практически аналогично. С одной стороны это удобно, с другой стороны это будет, видимо, первый случай высокоуровневого примитива в языке.

Автор: Unreal Man 13.06.07, 10:08
Цитата archimed7592 @
По указанной тобой ссылке я не нашёл передачи не-POD'а в элипсис.

Я показал смысл использования эллипсиса. Передача не-POD-объекта может быть, например, при проверке конвертируемости объекта одного типа в объект другого типа (у Александреску это, вроде, было).

Цитата archimed7592 @
Потому что это уже будет специальный тип в который будет пробинден this. А зачем? Много ньюансов и подводных камней.

Каких подводных камней?

Цитата archimed7592 @
И опять же, зачем?

Это к вопросу «а зачем нужно использовать операторы?»

Цитата archimed7592 @
И, в конце концов, для этого есть bind

Ну да, а ещё есть, например, std::plus:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x, y;
    ...
    // ну зачем же тут писать x+y, когда есть такой красивый способ?
    int result  = std::plus<int>()(x, y);


Цитата archimed7592 @
эээ... либо я чего-то не понял, либо

В том-то и дело, что это «либо» годится далеко не всегда. Недостаток этого способа в том, что он требует инстацирования обоих выбираемых типов, что иногда неприемлемо: тип, остающийся невыбранным, в ряде случаев не может быть успешно инстанцирован, из-за чего ты будешь хватать ошибки компиляции. Для реализации такого выбора приходится писать вспомогательный шаблон – на каждый случай свой.

Автор: archimed7592 13.06.07, 10:57
Цитата Unreal Man @
Недостаток этого способа в том, что он требует инстацирования
implicitly инстанцирований, если не ошибаюсь. Не могу придумать такого клинического случая, чтобы implicitly инстанцирование упало. Хоть с enable_if извращайся...

Автор: archimed7592 13.06.07, 23:55
Стандартная библиотека C++09


Более подробный обзор библиотечных изменений.




numeric_limits::max_digits10


digits10 означает(как и в C++03) кол-во десятичных цифр, которые не потеряют в точности после некоторых вычислений. max_digits10 означает кол-во десятичных цифр, которые тип вообще способен хранить.




iostream manipulator: defaultfloat


Манимулятор делает unsetf(ios_base::floatfield). Т.е. убирает эффект ранее применённых манипуляторов fixed или scientific.
Может кому-то это и понадобится :). Скорее новичкам.




Усовершенствованное использование const_iterator

Во-первых, с введением auto, следующий код будет использовать iterator, даже когда желаемым является использование const_iterator.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    vector< int > v;
    for (auto it = v.begin(); i != v.end(); ++i)
    { /* ... */ }
     
     
    // такой workaround не подходит в общем случае
    // т.к. iterator и const_iterator по идее имеют право быть
    // совершенно разными и несовместимыми типами
    for (const auto it = v.begin(); i != v.end(); ++i)
    { /* ... */ }

Также, в практике очень часто встречаются случаи, когда желаемо использование именно константного итератора в целях безопасности. К примеру, в ФП для этого приходится применять обёртки типа boost::cref или boost::lambda::constant_ref.
Пример из соответствующего документа(блин, как будет proposal по русски? :))
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void reset( double & d ) { d = 0.0; }
    void resee( double d ) { cout << ' ' << d; }
    vector<double> v;
    // распечатать v ...
    for_each( v.begin(), v.end(), reset ); // oops: хотели написать resee


В связи с этим для всех STL-совместимых контейнеров ввели новые ф-ции
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    const_iterator cbegin() const;
    const_iterator cend() const;
     
    // для реверсивных контейнеров
    const_reverse_iterator crbegin() const;
    const_reverse_iterator crend() const;

Теперь можно со спокойной душой писать auto it = v.cbegin() и не опасаться случайного изменения данных.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void reset( double & d ) { d = 0.0; }
    void resee( double d ) { cout << ' ' << d; }
    vector<double> v;
    // распечатать v ...
    for_each( v.cbegin(), v.cend(), reset ); // oops: compile-time error

Заметьте тенденцию, как на С++ становится всё проще и проще писать всё более и более надёжный код.
Чем дальше залезаю, тем больше понимаю, что С++ идеален и ни один холивар не докажет мне обратного :)




next, prior

Аналоги std::advance, но в отличие от advance возвращают изменённый итератор(точнее новый, равный изменённому).




is_sorted, is_heap

Помошники в собственных реализациях алгоритмов сортировки.




Diagnostics Enhancements

В связи с тем, что системно-зависимые телодвижения сообщают об ошибках немного иначе, чем принято в С++, а именно, ошибку описывает некое магическое число, добавили новых типов, для обёртывания этих чисел в исключения.
Этот пункт рассчитывался для включения в TR2 т.к. там появятся FileSystem и Networking, но, т.к. в С++09 появились потоки, которые тоже порой "ошибаются", решили включить этот документ в стандарт.
Итак, теперь errno.h является почти полностью соответствующим POSIX. В нём теперь определены макросы E2BIG, EACCESS, и т.д.
Добавлен хэдер <system_error> определяющий следующие типы(и переменные):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class system_error;
    class error_code;
    class error_category;
     
    extern const error_category& posix_category;
    extern const error_category& native_category;
     
    enum posix_errno
    {
    file_too_large,
    file_exists,
    // ...
    };

system_error - наследник runtime_error. Собственно говоря, потоковая, файловая и сетевая библиотеки будут бросать исключения именно этого(или унаследованного от этого) типа.
error_code - обёрточка для "магического числа".
error_category и иже с ним - определяет является ли ошибка posix-совместимая или же "родная" для системы.
posix_errno - перечисление, члены которого являются эквивалентами соответствующих ошибок EXXXX.




minmax, minmax_element

minmax(a, b) - возвращает упорядоченную пару значений, эквивалентную make_pair(min(a,b), max(a,b)).
minmax_element(first, last) - возвращает упорядоченную пару итераторов make_pair(min_element(first, last), max_element(first, last))(минимальный и максимальный в последовательности).
И две соответствующие перегрузки для использования с заданным предикатом(вместо используемого по умолчанию operator<).




long long goes to the Library

В связи с оффициальным статусом "новых" интегральных типов `long long` и `unsigned long long` стандартная библиотека обзавелась возможностями работы с этим типом(numeric_limits, hash, iostreams).




Unicode-строки

В связи с введением двух новых типов - char16_t и char32_t(а также литералов u"..." и U"..."), сделали поддержку UTF-16 и UTF-32 строк. Рассматривается возможность добавления несовместимого с basic_string класса для UTF-8(литерал E"...").
UTF-16 в большинстве случаев представляет одну букву одним символом, а суррогаты(в случае их неправильной интерпретации) могут повредить только одну букву(рядом с которой они находятся).
UTF-32 во всех случаях представляет одну букву одним символом.
В связи с этим для представления UTF-16/32-строк вполне подходит basic_string.
Добавлены специализации
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char_traits<char16_t>
    char_traits<char32_t>
     
    basic_string<char16_t> = u16string
    basic_string<char32_t> = u32string
     
    hash<char16_t>
    hash<char32_t>
    hash<u16string>
    hash<u32string>





Незначительные изменения type_traits

Исправлено около 40 проблем. Добавлены средства для lvalue/rvalue-references. Немного модифицированны характеристики конструкторов(в связи с облегчением ограничений на POD'ы и введением trivial-type и standard-layout-type).




Random Number Generation

Предложений улучшить средства стандартной библиотеки генерирования псевдослучайных чисел было великое множество. Тот же TR1 включает в себя некоторые. Всё это было пересмотренно, переработанно обобщено и, наконец то, включенно в стандарт.
Те кто знаком с boost::random могут не читать - поменялись только названия(ну и, может быть, добавлены новые генераторы).
    Введены концепции
  • Uniform random number generator.
    Представляет из себя функтор, каждый вызов которого возвращает очередное (псевдо)случайное число.
  • Random number engine.
    Расширение концепции Uniform random number generator для того, чтобы генератор можно было создавать, копировать и управлять им(seed, discard, etc.).
      Шаблонные классы, отвечающие концепции
    • linear_congruential_engine
    • mersenne_twister_engine
    • subtract_with_carry_engine
    • discard_block_engine
    • independent_bits_engine
    • shuffle_order_engine
    • xor_combine_engine

      Специализации шаблонных классов, отвечающих концепции
    • minstd_rand0
    • minstd_rand
    • mt19937
    • ranlux24_base
    • ranlux48_base
    • ranlux24
    • ranlux48
    • knuth_b
  • Random number distribution.
    Имеет смысл распределения.
    Представляет из себя функтор, который на вход берёт объект, отвечающий концепции Uniform random number generator, на выходы даёт распределение относительно параметра p(который задаётся при конструкции распределения или как второй аргумент функтора).
    Включённых в стандарт распределений(отвечающих концепции) много, список приводить смысла, думаю, не имеет.




Адаптация стандартной библиотеки к rvalue-references

Введены концепции MoveConstructible и MoveAssignable. Их смысл, думаю, должен быть понятен :)

auto_ptr объявлен устаревшим(deprecated), а на его замену пришёл unique_ptr.
unique_ptr отличается от auto_ptr тем, что у него есть возможность задавать deleter. Также, он разработан в расчёте на семантику перемещения и его конструктор копирования и копирующий оператор присваивания запрещены(недоступны).
Есть две частичные специализации для массивов переменной длины и для массивов фиксированной длины.

Как уже было упомянуто в первом посте, для rvalue-ссылок сделаны ф-ции помощники move и fwd.
Также добавились алгоритмы move, move_backward, предназначенные для "разрушающего std::copy" :)

К алгоритмам, которые изменяют последовательность путём перемещения/переставления элементов(sort, merge, etc.) добавлены требования на тип элемента: помимо того, что он должен был быть Swappable, он теперь ещё должен быть MoveConstructible и MoveAssignable.

Использовать unique_ptr теперь можно намного более надёжно, чем это было с auto_ptr.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f(unique_ptr< int >);
     
    unique_ptr< int > up1(new int(7));
    unique_ptr< int > up2 = up1; // compile-time error
    unique_ptr< int > up3 = move(up1); // ok
     
    f(up3); // compile-time error
    f(move(up3)); // ok
     
    unique_ptr< int[] > uparr(new int[256]); // за счёт специализации выберется правильный deleter(delete[] ptr).
     
    unique_ptr< IInterface > f2()
    {
        class Realization
            : public IInterface
        {
            /* ... */
        };
        // ...
        if (/* ... */)
            return unique_ptr< IInterface >(new Realization(/* ... */)); // ok
     
        unique_ptr< IInterface > up(new Realization(/* ... */));
     
        // ...
        return up; // compile-time error
        return move(up); // ok
    }
Т.е. теперь мы должны ясно выразить мысль, что мы хотим "отдать" объект(относится только к lvalue(-reference)).
    Классы которые получили семантику перемещения(конструкторы, операторы(operator= и другие), swap, etc.).
  • pair
  • unique_ptr
  • basic_string(string, wstring, u16string, u32string)
  • containers(vector, list, deque, etc. все, кроме array). "Недоконтейнер" valarray тоже в этом списке.
  • iterators(все итераторы, кроме появившегося move_iterator(ну ему это не особо и надо :)))
  • basic_streambuf, basic_iostream, etc.
  • все новые фичи сразу обзаводятся семантикой перемещения(tuple, к примеру).




<iostream> - header dependency

Наконец то :).
Теперь хэдер <iostream> подключает <ios>, <streambuf>, <istream> и <ostream>.
Вам возможно смешно, но, на самом деле, по стандарту(а мы говорим именно о нём ;)), подключив только <iostream> нельзя использовать ни std::endl, ни операторы << и >>(и это только один из примеров). Т.е. по стандарту многие программы могут просто не компилироваться.
Зная это я всегда писал #include <ostream> и #include <istream> и лично меня это телодвижение немного напрягало.
Также подумывают о создании отдельного хэдера <std>, включающего всю стандартную библиотеку(актуально для очень маленьких программ или проектов в которых используются precompiled headers).




enable_if, conditional

"Новые" шаблончики. Давно используются сообществом и пришли из boost.
enable_if предназначен для манипулирования принципом SFINAE на основе некоторого статического условия.
conditional позволяет выбрать один из двух типов на основе некоторого статического условия.




Внедрение std::string

В стандарте было около 20 мест, где использовался тип char * для передачи строки. Везде добавили перегруженные эквиваленты для std::string.
В основном затронуты локализация и fstreams.(ifstream::open, к примеру).




Yet another type-trait: decay

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template < class T > struct decay { typedef /* см.ниже */ type; };
    // Если T - массив, т.е. T <=> U[] или U[N], то decay< T >::type есть U *.
    // Eсли T - фунция, т.е. T <=> R(A1, A2, ...), то decay< T >::type есть T *, т.е. указатель на ф-цию.





Variadic Templates в стандартной библиотеке

Как уже было упомянуто, в библиотеке появилось следующее:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class... Types> class tuple;
     
    template<class Fn, class... Types> /* unspecified */ bind(Fn, Types...);
    template<class R, class Fn, class... Types> /* unspecified */ bind(Fn, Types...);
     
    template<class Function> class function; // undefined
    template<class R, class... ArgTypes> class function<R(ArgTypes...)>;

tuple - во-первых, может использоваться как идиома "списки типов". Во-вторых, может использоваться как std::pair на произвольное кол-во типов(и элементов).
bind - биндер из boost.
function - обёртка обобщённого функтора(тоже из boost).




TR1. Technical Report on C++ Library Extensions

Ну и конечно же tr1. С теми или иными модификациями, он полностью включенн в стандарт. Почти все сущности перенесены из пространства имён std::tr1 в пространство имён std.
Про содержание tr1 в следующий раз :).

Добавлено описание TR1.




Здесь описаны(упомянуты) далеко не все на текущий момент нововведения и исправления в Стандартной Библиотеке.




Обсуждение, дополнения и коррективы приветствуются. Всем спасибо за внимание.




remark: добавленна ссылка на продолжение(TR1): TR1. Technical Report on C++ Library Extensions.

Сообщения были разделены в тему "Грамматика C++"

Автор: mo3r 14.06.07, 04:47
Цитата archimed7592 @
блин, как будет proposal по русски? :)

Предложение
Цитата archimed7592 @
UTF-16 в большинстве случаев представляет одну букву одним символом, а суррогаты(в случае их неправильной интерпретации) могут повредить только одну букву(рядом с которой они находятся).
UTF-32 во всех случаях представляет одну букву одним символом.

:no: В UTF-32 один endpoint кодируется фиксированным набором байтов. Но одна буква может занимать более одного endpoint'а.
Цитата http://unicode.org/faq/char_combmark.html#7

Q: How should characters (particularly composite characters) be counted, for the purposes of length, substrings, positions in a string, etc.
A: In general, there are 3 different ways to count characters. Each is illustrated with the following sample string.
"a" + umlaut + greek_alpha + \uE0000.
(the latter is a private use character)
1. Code Units: e.g. how many bytes are in the physical representation of the string. Example:
In UTF-8, the sample has 9 bytes. [61 CC 88 CE B1 F3 A0 80 80]
In UTF-16BE, it has 10 bytes. [00 61 03 08 03 B1 DB 40 DC 00]
In UTF-32BE, it has 16 bytes. [00 00 00 61 00 00 03 08 00 00 03 B1 00 0E 00 00]
2. Codepoints: how may code points are in the string.
The sample has 4 code points. This is equivalent to the UTF-32BE count divided by 4.
3. Graphemes: what end-users consider as characters.
A default grapheme cluster is specified by the Unicode Standard 4.0, and is also in UTR #18 Regular Expressions at http://www.unicode.org/reports/tr18/.
The choice of which one to use depends on the tradeoffs between efficiency and comprehension. For example, Java, Windows and ICU use #1 with UTF-16 for all low-level string operations, and then also supply layers above that provide for #2 and #3 boundaries when circumstances require them. This approach allows for efficient processing, with allowance for higher-level usage. However, for a very high level application, such as word-processing macros, graphemes alone will probably be sufficient. [MD]


Добавлено
Opaque typedef
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1891.pdf)
Появятся новые виды typedef'ов, которые позволят создать новый тип, который ведет себя точно так же, как и какой-то другой, но между ними не будет неявного преобразования. Полезно, например, когда какой-то примитивный тип по всем свойствам подходит для описания чего-либо (например, координаты или физические величины или хэндлы объектов ОС), но неявные преобразования нежелательны.
Пример:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    opaque typedef double X, Y, Z; // Cartesian 3D coordinate types
    opaque typedef double Rho, Theta, Phi; // polar 3D coordinate types
     
    class PhysicsVector
    {
    public:
      PhysicsVector(X, Y, Z);
      PhysicsVector(Rho, Theta, Phi);
     
      ...
    }; // PhysicsVector

Автор: LuckLess 14.06.07, 06:35
Цитата archimed7592 @
prohibited:

Ура. Очень разд этой виче.
Только не понял.. (может не очень внимательно читал...?)
ссылка на ссылку как..? Опять запрещена? ведь T&& это rValue reference а не ссылка на ссылку.. ((

Добавлено
Цитата LuckLess @
T&& это rValue reference

вообще имхо не лучшее обозначение. лучшеб там.. ну хотябы T^ rvalueRef;

Автор: Unreal Man 14.06.07, 09:03
Цитата archimed7592 @
implicitly инстанцирований, если не ошибаюсь.

Не понимаю, к чему ты клонишь. Кстати, выбором типа проблема не ограничивается. Например, тебе нужно сделать swap для объектов двух неизвестных типов. Какие тут могут быть варианты? Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать, тогда остаётся только вызвать std::swap. Вот примерная реализация функции, вызывающей нужный swap, которая могла бы получиться со static if:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T>
        void MakeSwap(T &a1, T &a2)
    {
        static if (CHECK_METHOD(swap, void (T &))) // реализацию макроса CHECK_METHOD скипаю
            a1.swap(a2);
        else   if (CHECK_METHOD(Swap, void (T &)))
            a1.Swap(a2);
        else
            std::swap(a1, a2);
    }

Насколько всё лаконично, просто и понятно. А теперь сравни вот с этим извращением

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T>
        void MakeSwapHelper(T &a1, T &a2, IntToType<0>)
            { a1.swap(a2); }
    template <class T>
        void MakeSwapHelper(T &a1, T &a2, IntToType<1>)
            { a1.Swap(a2); }
    template <class T>
        void MakeSwapHelper(T &a1, T &a2, IntToType<2>)
            { std::swap(a1, a2); }
    template <class T>
        void MakeSwap(T &a1, T &a2)
    {
        const int variant =
            CHECK_METHOD(swap, void (T &)) ? 0 :
            CHECK_METHOD(Swap, void (T &)) ? 1 :
            2;
        MakeSwapHelper(a1, a2, IntToType<variant>());
    }

Цитата archimed7592 @
Хоть с enable_if извращайся...

А при чём тут, собственно, enable_if? :wacko:

Автор: Gunnar 14.06.07, 09:41
Цитата Unreal Man @
Кто-то может реализовать у своего класса метод с именем swap, кто-то другой – с именем Swap, ещё кто-то может вообще такой метод не реализовывать

Это к психиатру, однозначно. Если есть соглашения, им нужно следовать, если нет - их нужно принять. Если тип из 3-парти либы, к нему нужно написать адаптер, который реализует соглашения.

Добавлено
а если найдутся умники которые реализуют методы sWap, svap, SWaP, pomenyat_mestami, и.т.д. Ты их тоже в статик иф засунешь??? :wall: Бред!

Автор: archimed7592 14.06.07, 09:49
Цитата LuckLess @
ссылка на ссылку как..? Опять запрещена?
когда-то была разрешена? :unsure:

Цитата LuckLess @
ведь T&& это rValue reference а не ссылка на ссылку.. ((

ты наверное не понял, что && - интерпретируется как отдельный токен т.е.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef int & rint;
    typedef rint & rint2; // rint2 <=> rint <=> int & и так было, если не ошибаюсь аж с C++98
     
    typedef int && rrint; // rrint - не то же самое, что rint2
    typedef rrint & rint3; // rint3 <=> int && & <=> int & - по одному из правил сворачиваем ссылку



Цитата LuckLess @
ну хотябы T^ rvalueRef;

есть ещё такой момент, что T^ - используется в C++/CLI, а C++/CLI используется микрософтом, а в микрософте работает Герб Саттер, а он председатель комитета, если не ошибаюсь :)
ещё есть момент, что C++/CLI тоже разрабатывался комитетом.

Автор: mo3r 14.06.07, 10:10
Цитата Gunnar @
Это к психиатру, однозначно. Если есть соглашения, им нужно следовать, если нет - их нужно принять. Если тип из 3-парти либы, к нему нужно написать адаптер, который реализует соглашения.

Одно из предназначений шаблонов — интеграция кода из разных библиотек написанных разными людьми в разное время. Так что вполне нормальная ситуация.
А вообще, хотелось бы в языке видеть что-то наподобие Nemerle'вских макросов вместо программирования на шаблонах (например, см. http://rsdn.ru/article/nemerle/nemerleMacros.xml) (раз уж лисповские макросы не получится сделать). Это бы сильно упростило метапрограммирование.

Автор: LuckLess 14.06.07, 10:52
Цитата archimed7592 @
когда-то была разрешена? :unsure:

Нет.. не была.. но я все надеялся что будет разрешена.. но видимо зря.. ((

Добавлено
Цитата archimed7592 @
есть ещё такой момент, что T^ - используется в C++/CLI, а C++/CLI используется микрософтом,

Не вижу связи.. языки то разные.. какая разница что там чтото используется..
Цитата archimed7592 @
ты наверное не понял, что && - интерпретируется как отдельный токен т.е.

Да я понял.. просто хотел чтобы T&& было ссылкой на ссылку всеже..
и... если делать отдельный токен как && то надежда о ссылке на ссылку улетает.. ибо онаб выгладила как &&..

Автор: Gunnar 14.06.07, 11:03
Цитата LuckLess @
Не вижу связи.. языки то разные.. какая разница что там чтото используется..

Не совсем разные. C++/CLI - это надмножество С++. Т.е использование T^ в С++ неприемлемо.

Автор: LuckLess 14.06.07, 11:06
Цитата Gunnar @
C++/CLI - это надмножество С++.

:blink: Ту.. тогда уж это надмножество С++ стандарта 2003-го года, и в принципе может и не быть надмножеством 2009-го года.. Хотя я вообще не уверен что это может быть именно надмножеством.. как допускаются asm вставки в управляемый код?? но спорить не буду ибо с темой не знаком.

ладно.. какие там еще значки есть..
T% rvalueRef; пусть так тогда..

Автор: Gunnar 14.06.07, 11:20
Цитата LuckLess @
принципе может и не быть надмножеством 2009-го года

Ну дык будет новый стандарт C++/CLI "подогнанный" под С++ 2009

Автор: LuckLess 14.06.07, 11:28
Gunnar
Есть ли asm вставки в C++/CLI ?

Добавлено
Цитата Gunnar @
Ну дык будет новый стандарт C++/CLI "подогнанный" под С++ 2009

ну так пусть портят .Net всякими && а оставят нормальный С++ с нормальными значками.

ну да ладно есть еще
T$, T#, T%...

Автор: archimed7592 14.06.07, 11:38
Цитата LuckLess @
Нет.. не была.. но я все надеялся что будет разрешена.. но видимо зря.. ((

Не совсем понял... а как ты себе представляешь "ссылку на ссылку". Т.е. какой у неё будет смысл?


Цитата LuckLess @
Не вижу связи.. языки то разные.. какая разница что там чтото используется..
в c++/cli допустимо всё, что допустимо в с++ плюс .net навороты.


Цитата LuckLess @
T%

Уже занято тем же c++/cli :D


Цитата LuckLess @
как допускаются asm вставки в управляемый код?

Цитата LuckLess @
Есть ли asm вставки в C++/CLI ?

Вроде да. Там нету отличия уравляемого кода от неуправляемого. По крайней мере на уровне языка. Твори что душе угодно :)

Автор: LuckLess 14.06.07, 11:47
Цитата archimed7592 @
Не совсем понял... а как ты себе представляешь "ссылку на ссылку". Т.е. какой у неё будет смысл?

Такойже как у ссылки. т.е. ссылка на ссылку на ссылку на ссылку тоже самое что просто ссылка. Зачем это?
пример.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class BigClass
       {
    public:
       BigClass (const BigClass&) //very very slooow copy
          {
     
          }
     
       BigClass ()
          {
     
          }
     
       bool Func (int) const
          {
          std::cout << "Ы\n";
          return false;
          }
       };
     
    class LLClass
       {
    public:
       bool Func (BigClass&) const
       //workaround
       //bool Func (BigClass) const //no ref! copying BigClass! А если конструктор копирования вообще закрыт??
          {
          std::cout << "Ы\n";
          return false;
          }
       };
     
    int main ()
       {
       BigClass veryBigVariable;
     
       std::vector<LLClass> lotsOfBigClasses;
       std::for_each (lotsOfBigClasses.begin (), lotsOfBigClasses.end (),
                std::bind2nd (std::mem_fun_ref (&LLClass::Func), veryBigVariable));//error C2529: '_Right' : reference to reference is illegal
       }

Автор: archimed7592 14.06.07, 11:49
Цитата LuckLess @
Такойже как у ссылки. т.е. ссылка на ссылку на ссылку на ссылку тоже самое что просто ссылка

Эээ... так нет. Это ввели. Это и понимается под правилами сворачивания ссылок.

Автор: LuckLess 14.06.07, 11:57
Цитата archimed7592 @

Эээ... так нет. Это ввели. Это и понимается под правилами сворачивания ссылок.

Но как тогда обходится конфликт с &&.. ибо во время инстанциирования шаблона у меня получится T&& который будет означать ссылку на ссылку, а не ссылку на ravlue.

Автор: archimed7592 14.06.07, 12:00
Цитата LuckLess @
ибо во время инстанциирования шаблона у меня получится T&&

У тебя получится "T & &", а это не то же самое, что и "T &&". Опять повторяю, что "&&" и "& &" разные вещи. Аналогично как и "++" и "+ +".

Автор: LuckLess 14.06.07, 12:06
Цитата archimed7592 @
У тебя получится "T & &", а это не то же самое, что и "T &&".

т.е. для указателей я могу написать ** а для ссылок нада извращатся с "& &"? И если это изза того что гребанный C++/CLI есть на белом свете то я пойду отстреливать Билла.

Добавлено
T# хоть не занят эти дурацким языком? Если не занят то почему бы не использовать T#?
И вообще.. что будет взятие адреса у T&&? не T* же? Этож нада будет новый тип опять... указатель на rvalue..
чтото типа нада сделать
rvalue T& rvalueVar; //ссылка на rvalue
rvalue T* rvalueVar; //указатель на ravlue

Добавлено
Цитата LuckLess @
И вообще.. что будет взятие адреса у T&&? не T* же?

погоди.. неужели это будет тип T&&*? :blink:

Автор: archimed7592 14.06.07, 12:12
Цитата LuckLess @
т.е. для указателей я могу написать ** а для ссылок нада извращатся с "& &"?

Ты так можешь написать только потому, что такого токена как ** не существует и, соответственно, интерпретируется как два последовательных *

Цитата LuckLess @
И если это изза того что гребанный C++/CLI есть на белом свете то я пойду отстреливать Билла.

Да нет же. Не поэтому. Вот по текущему стандарту необходимо писать "set<set<int> >", а не "set<set<int>>". Ты же не пойдёшь отстреливать Кернигана за то, что он придумал ввести в язык побитовые сдвиги и токен ">>" интерпретируется именно как оператор сдвига, а не как две закрывающих скобки.

Автор: LuckLess 14.06.07, 12:17
Цитата archimed7592 @
Ты так можешь написать только потому, что такого токена как ** не существует

Правильно. Ссылка во многом похожа на указатель в плане "написания" типа.
Почему бы токен ** тогда не придумать.. вот все охренеют..
Когда я вижу ** я знаю что тут указатель на указатель, и обсолютно логично смотреть на && как на ссылку на ссылку.
Дохрена ведь разных значков есть, зачем использовать && мне непонятно..
T~, T`, T", T#, T:, T?, T.; еще думаю придумать можно..
запись T&& будет путать 100 процентно. Мое имхо что && в финальной версии не будет, ибо это бяка. Ключевое слово, или новый символ.. вот что должно быть.

Автор: archimed7592 14.06.07, 12:19
Цитата LuckLess @
T# хоть не занят эти дурацким языком? Если не занят то почему бы не использовать T#?

Да расслабься ты. Эти ссылки были предложены ещё в 2002 году и тогда, если не ошибаюсь и ^ и % были "свободны". Они и сейчас свободны. Просто, видимо, решили сделать синтаксис rvalue-ссылок похожим на синтаксис обычных(lvalue).



Цитата LuckLess @
И вообще.. что будет взятие адреса у T&&? не T* же?

Будет T *, означающая адрес ссылаемого объекта.

Дабы не разводить лишнего флейма, прочитай пожалуйста ещё раз, зачем были введены эти ссылки. Можешь в оригинале(n1377).

В двух словах: для того, чтобы отличать временные объекты от обычных, что может дать прирост производительности(при соответствующей поддержке со стороны реализации класса).

Добавлено
Цитата LuckLess @
Правильно. Ссылка во многом похожа на указатель в плане "написания" типа.
Почему бы токен ** тогда не придумать.. вот все охренеют..
Когда я вижу ** я знаю что тут указатель на указатель, и обсолютно логично смотреть на && как на ссылку на ссылку.
Дохрена ведь разных значков есть, зачем использовать && мне непонятно..
T~, T`, T", T#, T:, T?, T.; еще думаю придумать можно..
запись T&& будет путать 100 процентно.


LuckLess, как тебе такой момент, что нельзя будет писать int & & x? Между прочим, если бы можно было, то путало бы это не меньше.

Цитата LuckLess @
Мое имхо что && в финальной версии не будет, ибо это бяка. Ключевое слово, или новый символ.. вот что должно быть.
Ты не поверишь, но rvalue-ссылки уже включены в WP(рабочий черновик) и внедрены в туеву хучу мест стандарта(вся стандартная библиотека) и, поверь, никто не будет переделывать это на лад шапочек или процентиков.

Ещё раз напоминаю, что так решили с 2002 года и за 5 лет пока никому в голову не пришло, что это будет путать или ещё чем-то не устроит.

Автор: LuckLess 14.06.07, 12:28
Цитата archimed7592 @
В двух словах: для того, чтобы отличать временные объекты от обычных, что может дать прирост производительности(при соответствующей поддержке со стороны реализации класса).

Да я понял зачем они.. читал N раз (N > 2) ;)

имхо. Если есть ссылки на rvalue, то должны быть и указатели на rvalue. Почему? А почему бы и нет собственно?
былоб полезно.. и
если взятие адреса у T&& дает T*.. то вместо T& var = const_cast<T&> (rvalueRef);
можно написать T& var = *&rvalueRef;//а это не круто, для типизированного языка как ЭС с плюсами.

Ладно. Свое имхо сказал. Спорить не будем.. а то правда не флейм схожу уже..

Автор: archimed7592 14.06.07, 12:37
Цитата LuckLess @
имхо. Если есть ссылки на rvalue, то должны быть и указатели на rvalue. Почему? А почему бы и нет собственно?

Ты сможешь придумать практическое применение эти "указателям на rvalue"? Мне вот в голову ничего не приходит...



Цитата LuckLess @
если взятие адреса у T&& дает T*.. то вместо T& var = const_cast<T&> (rvalueRef);

Не понял при чем тут const_cast.
Понял чего ты хотел этим показать, но не уверен, что ты получишь то чего хотел...


Цитата LuckLess @
можно написать T& var = *&rvalueRef;//а это не круто, для типизированного языка как ЭС с плюсами.

Ты получишь точно такой же rvalue.
Попробуй в студии написать ostream &s = *reinterpret_cast< ostream * >(NULL); - получишь еггог т.к. нельзя делать неконстантные ссылки на временные(читай rvalue) объекты.

Автор: LuckLess 14.06.07, 12:44
Цитата archimed7592 @
Ты получишь точно такой же rvalue.
Попробуй в студии написать ostream &s = *reinterpret_cast< ostream * >(NULL); - получишь еггог т.к. нельзя делать неконстантные ссылки на временные(читай rvalue) объекты.

непроблема, яж псевдокодом написал.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ...
    T&& rvalueRef;
    T* ptr = &rvalueRef;//ok
    T& lvalueRef = *ptr;//ravlue превратился в lvalue

Цитата archimed7592 @

Ты сможешь придумать практическое применение эти "указателям на rvalue"?

Придумал уже)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ...
    T&& rvalueRef;
    T* ptr = &rvalueRef;//Ошибка! ravlue превратился в lvalue! Низзя так!
    rvalue T* ptrRValue = &rvalueRef;//ok
    T& lvalueRef = *ptr;//ravlue не превратился в lvalue
    const T& constRef = *ptrRValue ;//ok
    T&& rvalueRef2 = *ptrRValue ;//ok
    T& lvalueRef = *ptrRValue;//ошибка низзя так.

Автор: archimed7592 14.06.07, 13:04
LuckLess, не знаю насколько это можно считать разумным решением, но на данный момент стандарт трактует любую именнованную rvalue-ссылку как lvalue-ссылку. Т.е. на данный момент не нужно даже с указателями извращаться, чтобы "обмануть" компилятор.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f(T & a);
     
    void g(T && a)
    {
        f(a); // well-formed - несмотря на то, что "a" является как бы rvalue, мы без особых проблем передаём его по неконстантной lvalue-ссылке
        f(std::fwd(a)); // ill-formed - rvalue можно передавать только по константной lvalue-ссылке
    }
     
     
    T && a = ...;
    f(a); // well-formed


Могу добавить, что возможно, мы просто ещё не привыкли. С практикой всё встанет на свои места и многие из принятых комитетом решений станут понятными и "очевидными"("как это мы раньше этого не понимали - это же очевидно" :rolleyes:).
ИМХО, rvalue-ссылки примерно так же опасны, как и использование auto_ptr, но они того стоят.

Автор: LuckLess 14.06.07, 13:08
не.. ну с такой постоновкой я к rvalue ссылкам вообще негативно отношусь. ПОнятно что иногда, для оптимизации.. можно допустить опасные синтаксические конструкции.. но когда эти синтаксические конструкции можно сделать безопасными, а их безопасными не делают.. этого я не понимаю вовсе..

Добавлено
за что боролись.. на то и напоролись блин..
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f (double& d)
       {
       d = .555;
       }
     
    void ff (double&& d)
       {
       f (d);
       }
     
     
    int main ()
       {
       int i = 0;
       ff (i);
       }


Добавлено
:'(

Автор: archimed7592 14.06.07, 13:11
LuckLess, у всего есть rationale... Эти rvalue-ссылки 5 лет "вылизывали".

Автор: LuckLess 14.06.07, 13:12
Цитата archimed7592 @
LuckLess, у всего есть rationale... Эти rvalue-ссылки 5 лет "вылизывали".

Ну.. у них еще 2 года есть.. :rolleyes:

Автор: archimed7592 14.06.07, 13:19
Цитата LuckLess @
за что боролись.. на то и напоролись блин..

С чего ты взял, что это скомпилируется? :)
AFAIK, неявного каста из lvalue[-reference] of T в nonconst rvalue-reference of U нету.

Цитата LuckLess @
Ну.. у них еще 2 года есть.. :rolleyes:

Ну там пока до конца не вылижут, как правило в WP не включают :)

Добавлено
И не два года, а меньше, чем полгода(см. первый пост, начало) ;)

Автор: LuckLess 14.06.07, 13:23
Цитата archimed7592 @
AFAIK, неявного каста из lvalue[-reference] of T в nonconst rvalue-reference of U нету.

Гм... тут у нас int конвертируется в double и получается временная переменная типа double&& вродь все правильно да??

Цитата archimed7592 @
стандарт трактует любую именнованную rvalue-ссылку как lvalue-ссылку.

вот и все собстно..

Или мне пойти еще раз перечитать про rvalue reference.. ?? :D

Добавлено
Цитата archimed7592 @
И не два года, а меньше, чем полгода(см. первый пост, начало) ;)

так я и смотрел..
Цитата

К октябрю 2007 года комитет запланировал публикацию законченного черновика стандарта C++09(который будет доступен публике для рассмотрения и критики).
В октябре 2008 комитет внесёт окончательные коррективы в стандарт(и вот тут они одумаются!! :rolleyes:) и, наконец, на 2009 год(а тут уже все будет правильно... :rolleyes:) запланированна публикация нового стандарта "ISO/IEC 14883(2009): Programming Language C++".

Автор: archimed7592 14.06.07, 13:27
Цитата LuckLess @
Гм... тут у нас int конвертируется в double и получается временная переменная типа double&& вродь все правильно да??

С чего ты взял, что у нас тут что-то конвертируется. Для того, чтобы чего-то конвертировалось, компилятор должен решить, что "надо бы сконвертировать". А решения он принимает на основе набора правил из стандарта и правила "надо бы конвертировать lvalue of T в rvalue-reference of U", AFAIK, нету.

Добавлено
Цитата LuckLess @
так я и смотрел..

Ну там же четко сказано, что в 2008 комитет только внесёт коррективы(ну мало ли каких там Core/Library Defect Issues найдут).
Кардинально менять ничего не будут.
Потом до 2009 будут слушать нотации ISO по формальности языка и исправлять некоторые места на более формальный язык(не меняя смысла сказанного). Ну и в 2009 выпустят С++09.

Автор: LuckLess 14.06.07, 13:34
Цитата archimed7592 @
А решения он принимает на основе набора правил из стандарта и правила "надо бы конвертировать lvalue of T в rvalue-reference of U", AFAIK, нету.

тогда rvalue ссылка совсем не похожа на lvalue ссылку и использовать && для нее я теперь вижу еще меньше смысла..

Автор: archimed7592 14.06.07, 13:37
Цитата LuckLess @
тогда rvalue ссылка совсем не похожа на lvalue ссылку

а для lvalue-ссылки такое правило есть? ;)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f(double &);
     
    int i(0);
    f(i); // ill-formed

Автор: LuckLess 14.06.07, 14:17
Цитата archimed7592 @
а для lvalue-ссылки такое правило есть? ;)

есть
Цитата

A variable declared to be a T&, that is “reference to type T (8.3.2), shall be initialized by an object, or function, of type
T or by an object that can be converted into a T.

Цитата archimed7592 @
f(i); // ill-formed

не должно работать по другой причине
Цитата

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
— If the initializer expression
— is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or
...
An expression which holds a temporary object resulting from a cast to a nonreference type is an rvalue(this


а если ссылка const срабатывает
Цитата

Otherwise, the reference shall be to a non-volatile const type


но для T&&
это
— is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or
должно заменится на
— is an rvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or
как мне кажется..

пойду какнить прокурю весь ман по новым ссылкам на rvalue когда время появится..

Добавлено
не.. если нельзя написать
void f (T2&&);
...
T1 t;
f (t);//где есть преобразование T1 в T2.
то это нововведение выглядит вообще сомнительным. Это должно быть разрешено.

Автор: archimed7592 14.06.07, 14:46
Вот все изменения:
Цитата

An expression which holds a temporary object resulting from a cast to a nonreference typetype other than an lvalue-reference type is an rvalue (this includes the explicit creation of an object using functional notation (5.2.3)).
---
A variable declared to be a T& or T&&, that is ``reference to type T'' (dcl.ref), shall be initialized by an object, or function, of type T or by an object that can be converted into a T.
----
Otherwise, the reference shall be an lvalue-reference to a non-volatile const type (i.e., cv1 shall be const), or shall be an rvalue-reference.

Только не понял при чём тут reference-compatibility... она вроде для отношений наследования...

Автор: LuckLess 14.06.07, 14:53
Цитата archimed7592 @
Только не понял при чём тут reference-compatibility... она вроде для отношений наследования...

Цитата

is an lvalue (but is not a bit-field), and “cv1 T1” is reference-compatible with “cv2 T2,” or

битовые поля то уж точно не имеют отножение к наследованию :rolleyes:

Цитата archimed7592 @
Otherwise, the reference shall be an lvalue-reference to a non-volatile const type (i.e., cv1 shall be const), or shall be an rvalue-reference.

Вот.. эта добавочка позволит компилироватся коду
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f (T2&&);
    ...
    T1 t;
    f (t);//где есть преобразование T1 в T2.


ну.. мужики не глупые писали.. навернякак гдето есть добавочка которая не даст сделать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f (double& d)
       {
       d = .555;
       }
     
    void ff (double&& d)
       {
       f (d);
       }
     
     
    int main ()
       {
       int i = 0;
       ff (i);
       }

и
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    T&& rvalueRef;
    T* ptr = &rvalueRef;//ok
    T& lvalueRef = *ptr;//ravlue превратился в lvalue


хотя && будет резать мой глаз всю жизнь :lool: :lool:

Добавлено
вот подумал еще... я бы вообще не назвал бы это ссылкой..
пусть это будет именованный временный объект. без &&, а со значком какимнибудь.. или ключевым словом.
Тогда терминология бы упростилась. Имхо имхо имхо...

Автор: archimed7592 14.06.07, 15:48
Цитата mo3r @
Opaque typedef

Очень интересная штука, но, AFAIK, в С++09 её не будет :no-sad:

Автор: archimed7592 15.06.07, 00:27
Чего НЕ будет в С++09

С большой долей уверенности можно заявить, что следующие пункты не будут включены в готовящийся стандарт С++09. С не меньшей долей уверенности можно считать, что все эти пункты будут в следующим за С++09 стандарте С++1x.




Properties.(n1384, n1600, n1615)


Имеющиеся во многих языках свойства.
Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class foo
    {
        int get_value ();
        int _bar;
    public:
        property<int> bar =
        {
            read = get_value,
            write = _bar
        };
    };





Dynamic Libraries(n1400, n1418, n1428, n1496)

Все мы в той или иной мере используем *.dll, *.so и т.п. динамические библиотеки. Их написание и использование сопровождаются нестандартными расширениями компиляторов.
Комитет собирается стандартизировать динамические библиотеки.
Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    shared int i;        // shared linkage
     
    shared
    {
        int j;          // shared linkage
        static int k;   // internal linkage
    }
     
    shared class C
    {
        int c0;         // no linkage
        static int c1;  // shared linkage
        void f();       // shared linkage
    };
     
    template <class T> class D
    {
        int d0;         // no linkage
        static int d1;  // no linkage
        void f();       // no linkage
    };
     
    shared template <> D<int>; // D<int>::d1 and D<int>::f have shared linkage





Class namespaces(n1420)

При определении члена класса вне его(класса) определения приходится повсюду писать приставочку с именем класса.
Предлагается упростить реализацию класса внего его определения.
Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class MyClass
    {
        typedef int value_type;
        value_type foo(); // declaration
        value_type bar(); // declaration
    };
    MyClass::value_type MyClass::foo() // definition
    {
    }
    namespace class MyClass
    {
        value_type bar() // definition
        {
        }
    }
     
     
     
    // class definition
    class A
    {
        // declarations
    };
    // elsewhere
    // class namespace definition
    namespace class A
    {
        // definitions
    }
     
     
    template <class T> class A
    {
        // declarations
    };
    // elsewhere
    template <class T>
    namespace class A
    {
        // definitions
    }
     
     
    // full specialization
    template <> class A<void*>
    {
        // declarations
    };
    // partial specialization
    template <class T> class A<T*>
    {
        // declarations
    };
    // elsewhere
    // add definitions to a full specialization
    template<>
    namespace class A<void*>
    {
        // definitions
    }
    // add definitions to a partial specialization
    template <class T>
    namespace class A<T*>
    {
        // definitions
    }
     
     
     
     
    template <class T> class outer
    {
        template <class U> class inner
        {
            // declarations
        };
    };
    // elsewhere
    template <class T>
    namespace class outer
    {
        template <class U>
        namespace class inner
        {
            // definitions
        }
    }
    // equivalent
    template <class T>
    template <class U>
    namespace class outer<T>::inner
    {
        // definitions
    }
     
     
     
     
    class outer
    {
        class inner; // incomplete type
    };
    namespace class outer
    {
        class inner
        {
            // declarations and definitions
        };
    }
    namespace class outer::inner
    {
        // definitions
    }





Security and Standard C Libraries(n1461)

Включает в себя усовершенствования безопасности. Те самые, что многие видели в VS-8.0(7.0? 7.1?) - Security Enhancements in the CRT.
Речь о printf_s, fscanf_s, blablabla_s.
Т.к. стандартная библиотека С разрабатывалась в те времена, когда о безопасности думали в последнюю очередь, её архитектура в этом плане оставляет желать лучшего.
Предлагается модифицировать все стандартные ф-ции по нескольким критериям.
    В т.ч. следующие критерии
  • Ф-ции, которые берут на вход какой-либо буфер, должны также брать его размер.
    printf_s, strcpy_s, etc.
  • Ф-ции, которые берут на вход какой-либо callback, должны обеспечивать возможность хранения контекста между вызовами этого callback.
    qsort_s, bsearch_s, strtok_s, etc.
  • Все входные указатели ф-ция обязана проверять на валидность(не равность NULL).




Multimethods(n1529)

Мультиметод - это механизм, подобный виртуальным функциям, только выбор ф-ции, которая должна быть вызвана основывается на динамическом типе нескольких аргументов(в отличии от одного для вирутальных ф-ций - this).
Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct  shape            {...};
    struct  square   : shape {...};
    struct  triangle : shape {...};
     
    bool    overlap( virtual shape& a, virtual shape& b);
        
    bool    overlap( static square&   a, static triangle& b) {...}
    bool    overlap( static triangle& a, static square&   b) {...}
    bool    overlap( static shape&    a, static square&   b) {...}
    bool    overlap( static square&   a, static shape&    b) {...}





Expliciting default parameters(n1466)

Пока что для аргументов ф-ции по умолчанию есть чёткое требование: они должны быть в конце списка аргументов. В C++1x это требование скорее всего уберут и добавят возможностей работы с такими ф-циями.

Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void f(int x = 1, int y=2);
    void use()
    {
        f(default, 3);
        f( );
    }
     
     
    template <class T>
    T* allocAndClone (
        AllocatorType1 <T> alloc = MyAllocator <T>::instance(),
        T& prototype = T(),
        size_t size);
     
    template <class T>
    T* allocAndClone (
        AllocatorType2 <T> alloc = MyAllocator <T>::instance(),
        T& prototype = T(),
        size_t size);
     
    void process(char t = ‘\n’);
    void process(const char* = “end of line”);
     
    void use(void)
    {
        MyClonableClass* p;
        p = allocAndClone(
            default<AllocatorType1<MyClonableClass> >,
            default,
            10);
        
        process(default<char>);
        process(default); // error: ambiguity
        process(default<const char*>);
        process(default<float>); //error
    }





Nested Namespace Definition(n1524)

Предполагаемый синтаксис. Предлагается вместо этого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace grammars
    {
        namespace cplusplus
        {
            ...
        }
    }

Писать вот это:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace grammars::cplusplus
    {
        ...
    }





Implicitly-Callable Functions(n1611)

Неявно вызываемые ф-ции - это ф-ции, которые вызываются без применения постфиксного оператора "()".
Предполагаемый синтаксис.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    double pi() implicit { return 3.1415926; } // ICF
    double two_pi() implicit { return 2.0 * pi; } // ICF; note also the implicit call
     
    double & pi() implicit
    {
        static double pi = 3.1; // poor approximation
        return pi;
    }
     
     
    // primary definition of ICF template function:
    template< class T = double >
    T pi() implicit { return 3.141592653589793; }
    // specializations, each an ICF based on primary declaration:
    template<> float pi<float >() { return 3.14159F; }
    template<> long double pi<long double>() { return 3.141592653589793L; }
     
    template< class T >
    T area( T radius )
    {
        return pi<T> * radius * radius;
    }
     
     
    class Square
    {
    public:
        explicit Square( double s = 0.0 ) : side_(s) { }
        double & side() implicit { return side_; }
        // ...
    private:
        double side_; // length in cm
    };
     
     
     
     
    class SerialNumberGenerator
    {
    public:
        SerialNumberGenerator( int start_from ) : next_(start_from) { }
        int operator()() implicit { return next_++; }
    private:
        int next_;
    };
     
    SerialNumberGenerator unique( 1 ); // instantiation
    // ...
    cout << unique; // use





Contract Programming(n1942)

Идея добавить pre- и post-conditions, class invariant и block invariant.
Эти вещи очень часто встречаются в документации обобщённых классов. Также встречаются в стандарте в описании стандартной библиотеки.
Контрактное программирование имеет много плюсов. Хотя бы то, что код становится более самодокументированным. У компилятора появляется возможность делать некоторые предположения т.о. и возможность генерить более производительный код.
Отладка и тестирование станут проще. И т.п.

Предполагаемый синтаксис. Пример определения класса vector:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ///////////////////////////////////////
    // Tools
    ///////////////////////////////////////
     
    template< class Iter, class T >
    bool all_equals( Iter first, Iter last, const T& val )
    { /* for simplicity, let us assume T's can be compared */ }
     
    template< class Iter, class Size >
    bool equal_distance( Iter first, Iter last, Size size )
    { /* internal tagging mechnism so even input iterators can be passed */ }
     
    ///////////////////////////////////////
    // New vector interface
    ///////////////////////////////////////
     
    template< class T, class Alloc = allocator<T> >
    class vector
    {
        invariant
        {
            ( size() == 0 ) == empty();
            size() == std::distance( begin(), end() );
            size() == std::distance( rbegin(), rend() );
            size() <= capacity();
            capacity() <= max_size();
        }
        
        
    public:
        typedef Alloc                             allocator_type;
        typedef typename Alloc::pointer           pointer;
        typedef typename Alloc::const_pointer     const_pointer;
        typedef typename Alloc::reference         reference;
        typedef typename Alloc::const_reference   const_reference;
        typedef typename Alloc::value_type        value_type;
        typedef ...                               iterator;
        typedef ...                               const_iterator;
        typedef ...                               size_type;
        typedef ...                               difference_type;
        typedef reverse_iterator<iterator>        reverse_iterator;
        typedef reverse_iterator<const_iterator>  const_reverse_iterator;
     
                 vector()                  
                     postcondition { empty(); }
                    
        explicit vector( const Alloc& al )
                     postcondition { empty();
                                     al == get_allocator(); }
                    
        explicit vector( size_type count )
                     postcondition { size() == count;
                                     all_equals( begin(), end(), T() ); }
                    
                 vector( size_type count, const T& val )
                     postcondition { size() == count;
                                     all_equals( begin(), end(), val ); }
                
                 vector( size_type count, const T& val, const Alloc& al )
                     postcondition { size == count;
                                     all_equals( begin(), end(), val );
                                     al == get_allocator(); }:
                
                 vector( const vector& right )
                     postcondition { right == *this; }
        
                 template< class InIt >
                 vector( InIt first, InIt last )
                     postcondition { equal_distance( first, last, size() ); }
                    
                 template< class InIt >
                 vector( InIt first, InIt last, const Alloc& al );
                     postcondition { equal_distance( first, last, size() );
                                     al == get_allocator(); }
     
                 void reserve( size_type count )
                     precondition { count < max_size(); }
                     postcondition { capacity() >= count; }
                    
                 size_type capacity() const;
                     postcondition( result ) { result >= size(); }
                    
                 iterator begin()
                     postcondition( result ) { if( empty() ) result == end(); }
                
                 const_iterator begin() const
                     postcondition( result ) { if( empty() ) result == end(); }
                
                 iterator end();
                 const_iterator end() const;
     
        // ....
    };

Полную версию можно увидеть здесь.




Улучшенные возможности оптимизации(n1664, n1703)

Речь идёт о чём-то вроде спецификаций исключений, но, совсем в ином виде.
Если спецификации исключений никак в оптимизации не помогают(дай Б-г, если они не ухудшают производительность), то предложенные спецификаторы, вроде, должны.
Предложены спецификаторы: reading, writing, throwing, nothrow и pure.
Их назначение - описать поведение ф-ции с точки зрения, интересной оптимизатору. Все они, в отличии от спецификаций исключений являются частью типа ф-ции.

Предполагаемый синтаксис:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int f( int ) reading() writing() throwing();
    // ---------------------------------------------------
    // client code:
    #include <cerrno>
    int f( int x ) reading() writing(errno) throwing();
    // library code:
    #include <cerrno>
    int f( int x ) reading() writing(errno) throwing()
    {
        errno = 0;
        return 7 * x;
    }
    // ---------------------------------------------------
    // Отличия от спецификаций исключений
    int f( int ) throw()
    {
        throw 2; // compiles; ultimately calls unexpected()
    }
    int g( int ) throwing()
    {
        throw 2; // fails to compile: inconsistent with g’s declaration
    }
    // ---------------------------------------------------
    float hypotenuse( float s1, float s2 ) writing()
    {
        return sqrt( s1*s1 + s2*s2 ); // error; sqrt writes to errno
    }
    // ---------------------------------------------------
    // pure <=> no reading, no writing no updating(доступ к volatile объектам)
    float hypotenuse( float s1, float s2 ) pure
    {
        return sqrt( s1*s1 + s2*s2 ); // error; sqrt is not pure
    }
    // ---------------------------------------------------
    float hypotenuse( float s1, float s2 ) pure nothrow
    {
        try
        {
            pure
            {
                return sqrt( s1*s1 + s2*s2 );
            }
        }
        catch(...) { }
    }





Callable Pointers to Members(n1695)

Суть: указатели на члены можно будет вызывать. Относится как к методам, так и к членам-данным.
Вызвав указатель на член нужно передать ему первым аргументом указатель(или ссылку) на объект.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct X
    {
        void f() const;
    };
     
    int main()
    {
        std::vector<X> v;
     
        std::for_each( v.begin(), v.end(), &X::f ); // well-formed
     
        return 0;
    }


Добавлено


И как уже было сказано, не будет Opaque typedef: Новый стандарт C++: C++09 (сообщение #1601368)

Автор: =MOHAX= 18.06.07, 06:40
А шаблоны по прежнему надо будет писать только в одном файле? Т.е. разделять из в *.h/*.cpp нельзя?

Автор: archimed7592 18.06.07, 06:43
=MOHAX=, шаблоны и сейчас можно разделять в разные файлы - export template... Другой вопрос, что не все компиляторы это поддерживают.

Автор: gryz 18.06.07, 07:21
Цитата archimed7592 @
=MOHAX=, шаблоны и сейчас можно разделять в разные файлы - export template... Другой вопрос, что не все компиляторы это поддерживают.

А разве вообще есть такие компиляторы, которые полностью поддерживают export template??

Автор: archimed7592 18.06.07, 07:23
gryz, насчет полностью - не знаю, а так, AFAIK, comeau поддерживает...

Автор: LuckLess 18.06.07, 11:38
интеловский вроде тоже поддерживает export..

Автор: archimed7592 18.06.07, 13:14
Вроде поддерживает: Экспорт шаблонов в icc :lol:

Добавлено
Хотя, может и поддерживает - сам не пробовал... Может чел чего-то неправильно делал просто...

Автор: archimed7592 19.06.07, 00:48
Появилось обещанное описание TR1:
TR1. Technical Report on C++ Library Extensions

Автор: prografix 21.06.07, 09:03
А следующая конструкция будет легальной?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int n = 5;
    int a[n];

Автор: LuckLess 21.06.07, 09:32
Цитата prografix @
А следующая конструкция будет легальной?

int n = 5;
int a[n];

Надеюсь нет. Она не нужна в С++. хотя может для совместимости с С99..

Автор: archimed7592 21.06.07, 09:37
prografix, нет. :no:
Согласен с LuckLess - она не нужна :).

Автор: Devilguard 28.06.07, 20:05
Цитата

Expliciting default parameters(n1466)

Пока что для аргументов ф-ции по умолчанию есть чёткое требование: они должны быть в конце списка аргументов. В C++1x это требование скорее всего уберут и добавят возможностей работы с такими ф-циями.


Народ, это действительно кому-то нужно ???
Помоему это только усложнит читабельность кода. Когда видишь expr понять что это expr, а если сделать на манер паскаля, всегда сомнения будут. Да и не такие программисты лентяи чтобы 2 скобки не поставить.

Автор: =MOHAX= 29.06.07, 04:37
Devilguard Ты не внимательно читаешь.
Цитата archimed7592 @
Чего НЕ будет в С++09

:whistle:

Автор: archimed7592 01.07.07, 08:14
Цитата Devilguard @
Народ, это действительно кому-то нужно ???

Devilguard, представь себе, да :).
Эта альтернатива именованным аргументам, описанным у Страуструпа в D&E.
Суть проблемы в том, что порой, разработчикам библиотеки необходимо предоставить поведение по умолчанию, а мы хотим оставить это поведение таким же, за исключением одной маленькой детали, причём, мы хотим указать только эту деталь и всё. С именованными аргументами это можно сделать так же, как и в VB:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    window w0; // all default
    window w1(Color := 5, Height := 7);

Только для именованных аргументов в С++ есть некоторые преграды, а вот для Expliciting default parameters - нету...


Цитата Devilguard @
Помоему это только усложнит читабельность кода. Когда видишь expr понять что это expr, а если сделать на манер паскаля, всегда сомнения будут. Да и не такие программисты лентяи чтобы 2 скобки не поставить.

Чует моё сердце, что ты говоришь про Implicitly-Callable Functions.
Ничего не усложнит. Если ты пишешь expr, то где гарантия, что не будет вызвано неявное преобразование?

Автор: bor.is 10.09.07, 19:25
imo не хватает только break n; ! (в смысле брейк через несколько циклов)
даже в интерпретаторе php есть...
это единственное место, где приходится использовать метки

Автор: archimed7592 11.09.07, 05:28
Цитата bor.is @
это единственное место, где приходится использовать метки

А разве приходится? Неужели без них не обойтись? ;)
Я конечно слышал о том, что некто, разработчик драйвера TCP/IP стека для BSD сказал, мол, что если вам и удасться реализовать его без goto, то код будет ещё более запутанным и непонятным, но, всё равно, для меня воспользоваться goto - всё равно, что религию предать :).

Автор: Qraizer 13.09.07, 15:32
Тут где-то дальше по тексту была любопытная дискуссия.

Автор: archimed7592 13.09.07, 16:09
IMHO, тут дискутировать нечего, ибо
1. Использование goto вырабатывает не очень хорошую(читай очень плохую) привычку "мыслить goto'ми", что сказывается на алгоритмах, в которых без goto можно обойтись без любых костылей.
2. Пока пишешь код для себя - на здоровье(но учесть п.1), но когда другой человек начнёт читать твой код с goto, то, хорошо, если его не стошнит.
3. Всегда есть лаконичный способ избежать goto.

Автор: Hryak 13.09.07, 16:40
Цитата Qraizer @
Тут где-то дальше по тексту была любопытная дискуссия.

Ну, какая же это дискуссия. :) Вот у нас была дискуссия - исключения + стиль
:lol:

Автор: Qraizer 13.09.07, 18:48
archimed7592 Ты по ссылке-то ходил? Первый тезис вообще не аргумент, скорее ИМХО. Остальные два в ссылке опровергаются.
Hryak Просто Boroda всех быстро уболтал, а вы так быстро не смогли :P

Автор: archimed7592 13.09.07, 18:53
Цитата Qraizer @
Первый тезис вообще не аргумент, скорее ИМХО.

Ну, если сходить по ссылке Hryak'а, то можно увидеть, что это IMHO не только моё, но и Дейкстры :lol:.

Цитата Qraizer @
Остальные два в ссылке опровергаются.

Как можно опровергнуть второй тезис я не очень то себе представляю(что, проводили следственный эксперимент: кого стошнит, а кого - нет :lol:?), а опровержения третьему тезису я, увы, не нашёл :whistle:.

Автор: Qraizer 14.09.07, 09:46
Цитата archimed7592 @
Как можно опровергнуть второй тезис я не очень то себе представляю(что, проводили следственный эксперимент: кого стошнит, а кого - нет ?), а опровержения третьему тезису я, увы, не нашёл .
Ко второму тезису я просто подошёл творчески и стал понимать его буквально. Насчёт опровержения - так Boroda-е так никто и предложил безгоутный вариант его примера. Сам сможешь написать и сравнить с гоутным решением? Я, кстати, могу эту задачу ещё усложнить.

Автор: Hryak 14.09.07, 10:05
Цитата Qraizer @
Насчёт опровержения - так Boroda-е так никто и предложил безгоутный вариант его примера.

Объявляешь счетчики цикла с инициализацией нулем, убираешь во всех for содержимое до первой ; и убираешь goto с меткой. Всё.

Автор: gryz 14.09.07, 10:27
Цитата Qraizer @
Насчёт опровержения - так Boroda-е так никто и предложил безгоутный вариант его примера. Сам сможешь написать и сравнить с гоутным решением? Я, кстати, могу эту задачу ещё усложнить.

Тут скорее возникает вопрос, каким образом вообще возник подобный код.
Не существует ли более красивого алгоритма для решения задачи? В той теме это упоминается.

Автор: archimed7592 14.09.07, 10:50
Цитата gryz @
Тут скорее возникает вопрос, каким образом вообще возник подобный код.

Вот о том и речь - использование goto даже очень редко, в последствии порождает подобный код(см. 1-й тезис, который "скорее ИМХО").

Автор: Qraizer 14.09.07, 18:23
Цитата Hryak @
Объявляешь счетчики цикла с инициализацией нулем, убираешь во всех for содержимое до первой ; и убираешь goto с меткой. Всё.
Точно всё? Ничего не забыл? Попробуй. Хотя бы на двух вложенных циклах.
Чтобы не флеймить, вот сразу более сложный пример, который я имел в виду:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <io.h>
    #include <conio.h>
    #include <fstream>
    #include <iostream>
     
    int main()
    {
     int i, j, k;
     
     if(_access("savedstate.dat", 4)==0)
     {
      std::ifstream inFile("savedstate.dat");
      bool ok = true;
     
      ok = ok && inFile.read(reinterpret_cast<char*>(&i), sizeof(i)).gcount()==sizeof(i);
      ok = ok && inFile.read(reinterpret_cast<char*>(&j), sizeof(j)).gcount()==sizeof(j);
      ok = ok && inFile.read(reinterpret_cast<char*>(&k), sizeof(k)).gcount()==sizeof(k);
      if(ok && (inFile.good() || inFile.eof()))
      {
       std::cout << "The saved state is restored successful." << std::endl;
       goto resume;
      }
      return std::cerr << "The saved state restoring error. State file is wrong." << std::endl,
             1;
     }
     
     for(i=0; i<10; ++i)
      for(j=i; j<10; ++j)
       for(k=j; k<10; ++k)
       {
    resume:
        /* ... */
        if(kbhit() && getch() == '\x1B')
        {
         if(_access("savedstate.dat", 2)==0)
         remove("savedstate.dat");
     
         std::ofstream outFile("savedstate.dat");
         bool ok = true;
     
         ok = ok && outFile.write(reinterpret_cast<char*>(&i), sizeof(i)).good();
         ok = ok && outFile.write(reinterpret_cast<char*>(&j), sizeof(j)).good();
         ok = ok && outFile.write(reinterpret_cast<char*>(&k), sizeof(k)).good();
         if(!(ok && (outFile.good() || outFile.eof())))
          return std::cerr << "The state saving error." << std::endl,
                 1;
         return std::cout << "The state saved successful." << std::endl,
                2;
        }
       }
     if(_access("savedstate.dat", 2)==0)
      remove("savedstate.dat");
     ret
    }
Нет смысла указывать так много вложенностей, поэтому я их уменьшил с двенадцати до трёх. В принципе, я могу предложить метапрограммное решение, разумеется безгоутное, которое к тому же параметризирует количество вложенных циклов, но оно конечно же будет на порядок сложнее, чем структурное безгоутное.
Цитата gryz @
Тут скорее возникает вопрос, каким образом вообще возник подобный код.
Не существует ли более красивого алгоритма для решения задачи?
Ну как же? Там же ясно сказано - это было написано для возможности очень долгий алгоритм прервать с сохранением состояния и с возможностью продолжить с запомненного состояния. Ну и что, что это было под DOSом, которая была однозадачной? Счас-то ведь тоже вполне может возникнуть потребность перегрузить ОСь зачем-нибудь...

P.S. У этого форума есть возможность большие куски кода делать скроллируемыми, чтоб не занимали много места?

Автор: Hryak 16.09.07, 11:11
Цитата Qraizer @
Точно всё? Ничего не забыл? Попробуй. Хотя бы на двух вложенных циклах.

Да, забыл.

Цитата
Чтобы не флеймить, вот сразу более сложный пример, который я имел в виду

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <io.h>
    #include <conio.h>
    #include <fstream>
    #include <iostream>
     
    int main()
    {
        bool resuming = _access("savedstate.dat", 4)==0;
        for(int i=0; i<10; ++i)
            for(int j=i; j<10; ++j)
                for(int k=j; k<10; ++k)
                {
                    if (resuming)
                    {
                        resuming = false;
                        std::ifstream inFile("savedstate.dat");
                        bool ok = true;
     
                        ok = ok && inFile.read(reinterpret_cast<char*>(&i), sizeof(i)).gcount()==sizeof(i);
                        ok = ok && inFile.read(reinterpret_cast<char*>(&j), sizeof(j)).gcount()==sizeof(j);
                        ok = ok && inFile.read(reinterpret_cast<char*>(&k), sizeof(k)).gcount()==sizeof(k);
                        if(ok && (inFile.good() || inFile.eof()))
                            std::cout << "The saved state is restored successful." << std::endl;
                        return std::cerr << "The saved state restoring error. State file is wrong." << std::endl,
                            1;
                    }
     
                    /* ... */
     
                    if(kbhit() && getch() == '\x1B')
                    {
                        if(_access("savedstate.dat", 2)==0)
                            remove("savedstate.dat");
     
                        std::ofstream outFile("savedstate.dat");
                        bool ok = true;
     
                        ok = ok && outFile.write(reinterpret_cast<char*>(&i), sizeof(i)).good();
                        ok = ok && outFile.write(reinterpret_cast<char*>(&j), sizeof(j)).good();
                        ok = ok && outFile.write(reinterpret_cast<char*>(&k), sizeof(k)).good();
                        if(!(ok && (outFile.good() || outFile.eof())))
                            return std::cerr << "The state saving error." << std::endl,
                            1;
                        return std::cout << "The state saved successful." << std::endl,
                            2;
                    }
                }
        if(_access("savedstate.dat", 2)==0)
            remove("savedstate.dat");
        ret
    }

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

Суть в чем - использование goto может сделать структурированную программу неструктурированной. Это goto в вину и вменяют. Однако, приведенная тобой задача изначально имеет антиструктурированный элемент прямо в своей постановке. Логично, что неструктурированность из постановки задачи перетекает в решение и вполне естественно применение тут goto. Но можно его и не применять...

Автор: Qraizer 17.09.07, 10:42
Зачем же спорить? Количество потраченного времени на битие по клавишам и отладку в совокупности само рассудит. Текст вполне себе читабелен, хоть и чуточку менее интуитивен. Так что в целом авекватные результаты. Впрочем, переприсваивание параметров циклов в теле этих же циклов тоже как-то не совсем структурно, но это уже если придираться.
Только не надо мне приписывать защиту goto. Спорить я начал с аргументами archimed7592-а, а отнюдь не с мнением достаточно авторитетных теоретиков. В лице Дейкстры, в частности. И ссылку привёл просто в подтверждение тезиса не упомянутого по имени "разработчика драйвера TCP/IP стека для BSD".

Автор: archimed7592 17.09.07, 11:50
Цитата Qraizer @
Спорить я начал с аргументами archimed7592-а

Ок, все остались при своём мнение, вопрос исчерпан :lol:.

Автор: Hryak 17.09.07, 11:59
Цитата Qraizer @
Впрочем, переприсваивание параметров циклов в теле этих же циклов тоже как-то не совсем структурно, но это уже если придираться.

Совершенно согласен. . :)

Автор: amk 17.09.07, 17:50
Переприсваивание параметров вдобавок запутывает код почище тех же goto

Автор: archimed7592 01.10.07, 08:11
Времени дописать обещанный(и уже как полтора месяца валяющийся почти законченным) обзор TR2 совсем нет.
Также совсем нет времени просмотреть 4 пакета документов, вышедших с момента моего обзора, и написать что интересного там добавили.
Но вот, наткнулся на краткий отчёт Саттера об одной из последних встреч. Помимо того о чём я уже писал выше там есть это:


Language Support for Transporting Exceptions between Threads.
Языковая поддержка обмена исключениями между потоками исполнения.

(n2179)

Очень радует, что поддержка многопоточности в С++09 будет не просто "пустым звуком" на бумаге, а вполне реальной возможностью языка без необходимости через строчку использовать грязные хаки и особенности платформы для реализации чего-либо более реального, чем абстрактный hello world в два потока.

Суть нововведения в следующем: есть некий std::exception_ptr, который имеет семантику shared_ptr(т.е. разделяет владение - это в proposal явно не указано, но, насколько можно сделать вывод из описания copy_exception - это так).
Вы можете:
1. Получить указатель на текущее исключение - current_exception( )
2. Перебросить исключение на которое имеется такой указатель - rethrow_exception( exception_ptr p )
3. Получить указатель на копию исключения - copy_exception( E e ).

Зачем нужна последняя ф-ция я не особо догоняю(только если отдать другому потоку копию, а не оригинал, только зачем? :huh:). В proposal написано, что она нужна из соображений эффективности 0_о.

Автор: Славян 25.12.07, 14:40
Подскажите пожалуйста( может где я не так мыслю ? :-), собираются ли убрать или убрали уже предупреждение о том что строки вида :
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x;
    x|=-1;


или

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x;
    x &= 0;


выдают компилятором предупреждение ? // possible "ранняя операция перед присваиванием"...
Так просто финальный код короче, а смысл очевидный - зануление и постановка всех бит в 1.

Автор: Qraizer 25.12.07, 15:00
Ну, финальный код короче - ещё не факт, что быстрее. ИМХО, компилятору виднее, как это сделать эффективнее. Или ты думаешь, что он настолько тупой, что при случае сам до такой оптимизации не додумается? Додумывается, сам иногда видел, а где не видел, значит оптимизатор не посчитал нужным. Вывод: варнингу быть, ибо по-любому имеет место юзанье переменной до инициализации. Не надо привыкать к хакам, может аукнуться.

Автор: Славян 26.12.07, 13:18
1.Да, я думаю, что он столь тупой.
2.Это не оптимизатор считает что-то нужным, а люди думают, сколько они сил готовы потратить, чтобы усилить оптимизатор. И часто махают рукой.
3.Использования переменной нету, ибо тут она вчистую превращается в ноль или полностью забивается единицами.
Но, в целом, жаль, что Warning'у быть... :-(

Автор: archimed7592 26.12.07, 13:21
Цитата Славян @
Использования переменной нету

А здесь тоже нету?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x = ...;
    int y = x - x;

Автор: Славян 26.12.07, 13:33
Да, и здесь компилятор (оптимизатор?) должен обнулить и всё. И чихать он должен хотеть на вычитание. Или я чего-то не понимаю? Ж:-)

Автор: archimed7592 26.12.07, 13:55
Я попробую привести пример, который, возможно, прояснит ситуацию.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A
    {
        A(int value)
            : value(value)
        { }
     
    protected:
        A operator -(const A &rhs)
        { return A(value - rhs.value); }
     
    private:
        int value;
    };
     
    int main()
    {
        A x = 100;
        A y = x - x; // error
    }

Здесь, несмотря на то, что происходит очевидное зануление, компилятор выдаст не просто предупреждение, а ошибку компиляции. Просто потому, что по Стандарту такой код корректной реализацией компилировать не должен(ill-formed code).

Так вот, есть в Стандарте такое понятие как UB(undefined behavior). Это тоже ошибка, но корректная реализация имеет право скомпилировать код(и, как правило, скомпилирует). UB относится к тем случаям, которые далеко не всегда можно детектировать, так что реализация в праве вообще молчать как партизан на такую строку. Но, хорошая реализация в детектируемых случаях старается предупредить программиста, что он пользуется очень опасной конструкцией. Собственно говоря, об этом Вас компилятор и предупреждает. Он не говорит, что это работать будет как-то не так. Он говорит, что такой код по Стандарту имеет право вывести на экран "i'm is a result of code, written by foolish programmer". Если вы можете позволить себе пользоваться такими конструкциями, то можете успешно посмотреть на это предупреждение сквозь пальцы, а то и вообще выключить предупреждения в принципе(зачем они вам - вы же намного умнее компилятора с оптимизатором, правда, с такими амбициями, рекомендую посмотреть в сторону языка ассемблера).

Автор: albom 26.12.07, 14:03
Ну для int может и не актуально, но вот если бы там был double, то x - x уже нельзя заменить на 0.

Автор: Славян 26.12.07, 14:06
Спасибо.
Да я давно туда смотрю и хожу, но С не бросишь полностью. Просто тут пример с классами, это принципиально громаднее выглядит, чем int y=x-x; И конечно хочется, чтобы на просто выглядящие вещи оптимизатор бы обращал побольше внимания, а не заваливал предупреждениями по делу и без оного.
Ладно, буду сожалеть про себя далее... :-( :-)

Добавлено
И чем double хуже? Там ноль тоже нормальный, не надо ля!

Автор: archimed7592 26.12.07, 14:11
Цитата Славян @
Там ноль тоже нормальный, не надо ля!

Там результат вычисления неточный. А, если оперировать с нечислами, представленными double'ом, то вообще ни о каком нуле речи быть не может :).

Автор: Славян 26.12.07, 14:17
Я знаю. Просто за много лет у меня не было ни одной программы где я бы пользовался нечислами в double. А все неточности расчётов с числами тут оптимизатор должен забыть и написать обнуление.

Автор: albom 26.12.07, 14:18
Если x - конечное число, то получим вполне точный ноль. Тут все ок.
Но, если не инициализировать x, то там может оказатся значение +inf, -inf или даже NaN. Вот тут-то вычитание и вернет нам далеко не ноль.

Добавлено
Эх, опять я торможу с ответами :)

Автор: archimed7592 26.12.07, 14:20
Цитата Славян @
Просто за много лет у меня не было ни одной программы где я бы пользовался нечислами в double

Вы не поверите - они, порой, сами по себе появляются :).

Цитата Славян @
А все неточности расчётов с числами тут оптимизатор должен забыть и написать обнуление.

Молодой человек, мы разговариваем о С++ или о каком-то, вымышленном Вами языке?(вопрос не риторический)

Автор: amk 26.12.07, 18:30
Славян и другие
Не вижу смысла пользоваться такими заумными конструкциями. Если ты знаешь, что там ноль, то так и пиши =0, нечего компилятору голову морочить, и тем кто потом программу читать будет (в основном им).

Автор: Qraizer 27.12.07, 19:48
Славян
Цитата Славян @
2.Это не оптимизатор считает что-то нужным, а люди думают, сколько они сил готовы потратить, чтобы усилить оптимизатор. И часто махают рукой.
Вот когда ты будешь обладать не меньшим количеством информации, чем оптимизатор, тогда ты сможешь считать, что усиливаешь его. Заметь, он обладает куда бОльшей информацией о сгенерированном коде, чем ты, рассматривая ассеблерный листинг вблизи места предполагаемого вмешательства. А пока ты не доказал, хотя бы себе, что:
  • уменьшив длину одной инструкции, учёл влияние этого при их выборке из кеша;
  • сможешь конкурировать с оптимизатором в прогнозировании драк за строки кеша данных и в предсказании переходов и следовательно более грамотно, чем он, сможешь расставить обращения к памяти в теле циклов и развернуть их в оптимальное количество раз;
  • в ассеблерных вставках сможешь грамотно переупорядочить порядок инструкций для исключения простоя декодеров и полноценной загрузки конвейеров и исполнительных блоков процессора и исключения их чрезмерных простоев;
  • итп
считай, что ты оптимизатору будешь только мешать, ибо он тебя послушается даже в ущерб своей задаче. Даже выиграв локально тут, в целом можешь проиграть крупнее где-нибудь там, и не заметить этого.

Автор: Flex Ferrum 27.12.07, 20:54
Qraizer, все это замечательно. Только здесь же в холиварах ассемблерщики показывают, что оптимизатор (практически во всех перечисленных тобою пунктах) сливает проф. ассемблерщику. Т. е. я хочу сказать, что какие-то оптимизаторы, может быть, и умеют оптимизировать так, как ты описал, но таких - единицы. И те же компиляторы от Intel и Microsoft такими свойствами не обладают. Если считаешь иначе, прошу вот в эту: http://forum.sources.ru/index.php?showtopic=209970 тему.

Автор: Qraizer 28.12.07, 14:17
Чесговоря, не нашёл я в этом топике того, что ты мне хотел показать. Читал не весь - большой уж больно - так что ткни меня носом конкретнее, плз. Либо я не понял, чтО ты хотел мне показать. Я подумал что "ассемблерные профессионалы, затыкающие оптимизаторы без особых усилий - это не редкость". Так что проясни, если не трудно.
Далее. Оптимизаторы, которые я имел в виду, отнюдь не редкость. Только надо предоставить им достаточно информации для работы. Например, размеры строк кеша зависят от процессора, поэтому пока не укажешь оптимизатору каким-нибудь ключиком /G7 /QxP, на чём будет исполняться программа, максимум отдачи не получишь. Согласен, что несерьёзно настолько конкретизировать исполнительную платформу, но во-первых, ручной ассемблерный код тоже подвержен влиянию этой проблемы, во-вторых, есть ещё, к примеру, /QaxW, в-третьих, и вручную тоже можно разделить код под разные процессоры путём __declspec(cpu_specific) и __declspec(cpu_dispatch) и даже не использовать при этом ассемблер. Что касается потери оптимизации в общем при некотором выигрывании в частном, то /Qip сможет помочь, причём даже есть ассемблер, тут я слегка сутрировал, признаю. А для экстремалов есть /Qipo, только при его применении в зависимости от размера проекта в ожидании окончания его компиляции можно зачаржить часы в недельном отчёте от "отправился на обед" до "уехал на пикник". Для эстетов имеется /Qprof_gen и /Qprof_use, заодно и целевой модуль может получиться меньше в разы. Ну и наконец, всё это фуфло по сравнению с jit-time компиляцией. Правда, это уже не для плюсов. По крайней мере, пока. Недаром байт-кодинг в последнее время получает всё большее расспространение, ИМХО дойдёт и до плюсов. Зато решает проблемы с зависимостью от исполнительной платформы. Только, боюсь, здесь уже ассемблер будет просто в оффсайте. А если попытаться его заменить каким-нибудь специальным байт-кодным ассемблером, то это опять-таки внесёт уровень трансляции, который ассемблерные вставки призваны вроде как наоборот - убирать. P.S. Примеры управления оптимизацией взяты от Intel Compiler. Несколько слов в защиту обоих точек зрения: генерим ассемблерный вывод и внимательно рассматриваем комменты Intel Compilr-а, которыми он подробненько расписал, что по его мнению будет происходить при исполнении кода - всякие там штрафы от простоев, вероятности предсказаний переходов, распределение данных по строкам кеша и вероятности промахов, итп, и только после этого приступаем к попыткам помочь ему в каких-нибудь конкретных местах. Это я ещё смогу понять.
В заключение. Я не отрицал возможности переплюнуть оптимизатор, так и сказал: "...пока ты не доказал, хотя бы себе,...". Если удалось доказать - то флаг в руки. Но лично мне это неинтересно. Каждый получает удовольствие от разных аспектов творческой составляющей нашей профессии. И я уже давно бросил соревноваться с компилятором в такой рутинной (для меня) области как бак-энд оптимизэйшн. Когда понадобилось написать _ecvtl() и _fcvtl для нативного x86-го long double, которые как известно MSVC для Win32 не поддерживает, тогда я этим занялся. Писал на асме и оптимизировал под P6. И - не буду скромничать - переплюнул их собственный _ecvt в три раза в производительности, а аналогичную C-реализацию компилятор соптимизировал хуже на 15%. И только добавив /arch:SSE2, я смог добиться от компилятора большей эффективности, что всё равно было неприемлимо, ибо функция как бы библиотечная. Потратил на это около двух дней - примерно впополаме на создание/отладку и оптимизацию/отладку. Теперь могу гордиться, мол, моя функция экономит вам столько-то там миллисекунд на выводе каждого long double. Вот пишу сейчас и думаю, нафиг я на это потратил столько времени? Разве что здесь похвастаться, а так практического эффекта никто не заметил и никогда не заметит. Да и было это один-единственный раз за последние лет восемь.
В общем, мне это неинтересно, я лучше найду более другие причины потратить своё рабочее время. С пользой в сторону переносимости, гибкости, масштабируемости и надёжности. Если у кого другое ИМХО, да пожалуйста. Только для предотвращения воизбежания пусть почитает обо всём этом тут, ну а там пусть делает свои выводы и поступает сообразно им. Да и не всем "двигать мировую экономику и внедрять демократию", кому-то надо "...быть спортсменом или клоуном, чтоб политики и демократы могли иногда отдохнуть от подгаживания своим коллегам и расслабиться под зрелище смачной драки футбольных фанатов или там резню гладиаторов..." © Гай Юлий Орловский.

Автор: Славян 28.12.07, 14:54
Блин, как всё сложно. Просто, поверите ли нет, ну дураку понятно, что код вида :
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov edi, edi
    push ebp
    mov ebp, esp
    mov eax, [eax+$xxyyzzww]
    pop ebp
    ret

// вроде User32.dll
или вида
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    fld1
    fstp dword ptr [EBP+$xx]
    fldz
    fstp dw [EBP+$yy]
    fldz
    fstp dw [EBP+$zz]
    fldz
    fstp dw [EBP+$ww]
    fld1
    fstp dword ptr [EBP+$hh]
    ...

// glu32.dll
не является оптимальным ну никак.
И всякие оптимизации, приводящие к коду типа 1-примера( когда нефиг напрягаться компилятору за стэк), очевидно глупее моих :
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov eax, [eax+$...]
    ret

Мне не нужно изучать кэши и промахи в него, ибо я суть оптимизатора вижу. И уж поверьте хоть и смотрю 'листинг вблизи места', вижу больше, чем он.

Ну на кой ляд делать код
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    fld ...
    fld ...
    fxch ST(1), ST(0)
    ...
?

И таких примеров у меня уже 76 категорий накопилось. Собираю, знаете ли ;-)
Баг ниже вообще заполонил Microsoft'овские dll-ки.

[BUG70]
648B05xxyy0000 mov EAX, FS:[$0000yyxx]
:или
64A1xxyy0000 : mov EAX, FS:[$0000yyxx]
: можно сэкономить на нулях! (используя префикс
: смены способа адресации) так :
6764A1xxyy : mov EAX, FS:[$yyxx]
: выигрыш = 2 байта(в 1 случае), или 1 байт (во втором)!
: истинность = 100% (вроде бы)
: идея баг'а из WinXP sp2 : user32.dll

Автор: Qraizer 29.12.07, 18:33
Мда, маловаты у тебя фрагменты, как-то ты черезчур буквальНо поспринял слово "вблизи". Так что на безгрешность не претендую, однако...
С первым примером для меня всё ясно. Первая инструкция - это двухбайтный ноп. Для чего он там - это вопрос уже не ко мне. Даже после самых дерьмовых оптимизаторов просто так нопы никогда не остаются, т.е. к оптимизации он не имеет прямого отношения. Игра со стековым фреймом - так без него плохо живётся всяким там отладчикам, профайлерам, кодековерам итп. А экспортируемые функции без стекового фрейма - это вообще нонсенс. Менеждер виртуальной памяти может это не одобрить по полной программе. Вообще же, ставишь галку компилеру, и он напрочь забывает о фреймах. И наоборот: не поставил галку - компилятор обязан создавать фреймы. Что, скажешь ни разу этой галкой не пользовался? Что-то я не пойму твоего недовольства этим фрагментом.
Второй фрагмент вполне оптимален. Наверняка компилятору было сказано ключиком, чтобы он использовал строгое соответствие стандарту IEEE при работе с вещественной арифметикой. Вот он и не стал заменять FPU операции на CPUшные. А дальше я бы лучше уточнил, для какого процессора это оптимизация. Я вижу множество только-записей на шину, разделёнными паузами для предотвращения простоя блока предвыборки, который имеет меньший приоритет при конкуренции за грант шины по сравнению с записью данных. Паузы маленькие, всего в две микроинструкции + имеем простаивающий третий декодер, который компилятору просто нечем загрузить (впрочем, для P5 - этот код оптимизарован почти абсолютно), но если вдруг что, то одна из них даст возможность простаивающему блоку предвыборки успеть озадачить кеш, и в случае промаха теперь уже записи будут откладываться в буфере в ожидании гранта на шину. Вносимые fldz и fld1 паузы сами по себе не вредят производительности, т.к. эти команды на самом деле просто возвращают некое значение, которое тут же отправляется в память, т.е. в блоке неупорядоченного исполнения все они в совокупности не будут порождать никаких штрафов из-за зависимости по ST(0). Точнее, это всё-таки может случиться, но зависеть будет не от этого кода, а от окружающего контекста.
Третий фрагмент - это вообще классика, начиная с P5. То, что тебе показалось глупостью, на самом деле позволяет выполняться последней загрузке параллельно со следующей после FXCH FPU-операцией, т.к. FXCH - это чуть ли не единственная инструкция, которая парабельна почти всем остальным FPU инструкциям (исключая трансцендентные, кажется). Выполняя её одновременно с предыдущей, мы ничего не теряем в тактах, зато "переименовываем" ST(0) в (в данном случае) ST(1), и следовательно какая-нибудь следующая FADD ST(0), ... будет работать параллельно с загрузкой в ST(1). Для P6 это имеет более слабый эффект, особенно на нативном для x86 long double, но всё-таки имеет.
Четвёртый пример ты бы постеснялся приводить, если бы е лез в бутылку, а внимательнее внимал. Этот "баг" самое что ни на есть распространённое средство выравнивать длины инструкций под наиболее оптимальные. Так же как с нопами - иногда выгоднее использовать покороче, иногда - подлиннее. А вот твоя "оптимизация" предлагает поставить два префикса подряд, причём один из них AS. Ну-ну.
Я думаю, не имеет смысла рассматривать все 76 категорий. Это число как-то подозрительно напоминает длину моего конспекта по оптимизации i486-P7, там было что-то около 70 пунктов. Да и archimed7592 прав - ты спросил, я ответил, а дальше давай куда-нибудь от этого топика, если будет желание. Только до окончания праздников, боюсь, у меня будут сложности с on-line-ом. И кстати, archimed7592 напомнил, инициализация присваиванием и твоя логической операцией нагружают разные исполнительные блоки процессора. Именно поэтому иногда оптимизаторы используют твою идею, иногда нет. Нагружает так, чтобы получилось поравномернее, а если в данном кокретном случае пофигу, то просто юзают "прямой" способ.

Автор: trainer 31.12.07, 08:02
Вы когда спорите со Славяном, держите в уме вот это: Определить бинарный файл (сообщение #1816742) и вот это: Определить бинарный файл (сообщение #1817916) :)

Автор: vedmak 12.01.08, 15:12
Я только начинаю учить шаблоны :) поэтому мне не очень понятно тут все :) В первом сообщении думал -
Цитата
что текущий стандарт, для заданного выражения E(a1,a2,...,aN), которое зависит от параметров a1,a2,...,aN, не позволяет написать такую ф-цию(или функтор), которая будет эквивалентна этому выражению.

Думаю как это так? Ну например a1+a2+a3. Почему нельзя сделать функцию с параметрами a1,a2,a3, в которой будет строчка return a1+a2+a3?

Потом идет первый пример - где "Всё бы хорошо, но нельзя сделать вызов f(1, 2, 3)."

Попробовал сейчас в VS98:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // gh.cpp : Defines the entry point for the console application.
    //
     
    #include "stdafx.h"
     
     
    void g(int a1, int a2, int a3);
     
    template < class T1, class T2, class T3>void f(T1 &a1, T2 &a2, T3 &a3){    g(a1, a2, a3);}
     
     
    int main(int argc, char* argv[])
    {
        f(1, 2, 3);
        return 0;
    }
     
    void g(int a1, int a2, int a3)
    {
    }


Компилируется на ура! В общем вы слишком какие-то продвинутые вопросы обсуждаете...

Автор: Qraizer 12.01.08, 16:01
Первое: VS98 компилировать не умеет. Второе: VC98 (или MSVC98, если угодно) является инструментом 10-летней давности, который не удовлетворяет требованиям текущего стандарта, и проверять им код на соответствие текущему стандарту, согласись, по меньшей мере неразумно. Возми чё поновее и повтори попытку. Третье: это ещё не всё, твой код некорректен, т.к. не каждая g(), имеющая ровно 3 параметра, сможет быть вызвана вот такой вот твоей f(). Собственно это как раз и утверждалось в цитированном тобой фрагменте.

Автор: maxutov 15.02.08, 09:29
а какие компиляторы уже поддерживают стандарт?

Автор: b-a1 15.02.08, 20:56
Цитата maxutov @
а какие компиляторы уже поддерживают стандарт?

А какой сейчас год? :rolleyes:

На второй странице говорилось следующее:
Цитата archimed7592 @
К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. расширение vs-8.0 для поддержки template aliases и т.д.
:)

Автор: maxutov 19.02.08, 12:44
Цитата b-a1 @
Цитата maxutov @
а какие компиляторы уже поддерживают стандарт?

А какой сейчас год? :rolleyes:

На второй странице говорилось следующее:
Цитата archimed7592 @
К слову уже сейчас можно скачать расширения g++ для поддержки variadic templates, concepts. расширение vs-8.0 для поддержки template aliases и т.д.
:)

я имел ввиду беты
много новых интересных вещей придумано в С++09 для приятного общения
тестирование нужно проводить заранее

Автор: b-a1 19.02.08, 16:43
maxutov, в этом плане, всё немного проще :).
Даже текущий стандарт(2003 года) полноценно поддерживается разве что comeau и то, не знаю в какой степени... Что же касается будущего стандарта - во первых, неизвестно, когда его окончательно утвердят(т.е. провозгласят 14882 устаревшим, а 14883 "актуальным"), не говоря уже о полном соответствии современных компиляторов.

Автор: Flex Ferrum 31.03.08, 18:40
Не могу не поделиться новостью. Оригинал здесь:
http://herbsutter.spaces.live.com/Blog/cns...B!785.entry

На последнем заседании комитета по стандартизации среди всего прочего в стандарт C++0x включили поддержку lambda-функций. Полное описание можно прочитать в статье. Вкратце, новый стандарт будет допускать следующий код:
Вывод коллекции на консоль:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Writing a collection to cout, in today's C++, option 2:
     
    copy( w.begin(), w.end(),
              ostream_iterator<const Widget>( cout, " " ) );
     
     
    // Writing a collection to cout, in C++0x:
     
    for_each( w.begin(), w.end(),
                    []( const Widget& w ) { cout << w << " "; } );


Поиск элемента в массиве:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Calling find_if using a functor, in today's C++:
     
    // outside the function, at namespace scope
    class GreaterThan {
      int weight;
    public:
      GreaterThan( int weight_ )
        : weight(weight_) { }
      bool operator()( const Widget& w ) {
        return w.Weight() > weight;
      }
    };
     
    // at point of use
    find_if( w.begin(), w.end(), GreaterThan(100) );
     
     
    // Calling find_if using a lambda, in C++0x:
     
    find_if( w.begin(), w.end(),
                 []( const Widget& w ) -> bool { w.Weight() > 100; } );


Алгоритмы как циклы:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for_each( v.begin(), v.end(), []( Widget& w )
    {
      ...
      ... use or modify w ...
      ...
    } );
     
    transform( v.begin(), v.end(), output.begin(), []( const Widget& w ) -> AnotherType
    {
      ...
      return SomeResultCalculatedFrom( w );
    } );


Выполнение кода в другом потоке:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mypool.run( [] { cout << "Hello there (from the pool)"; } );


Также приняты в стандарт новый (альтернативный) формат объявления методов:
direct-declarator:
direct-declarator ( parameter-declaration-clause ) cv-qualifier-seqopt ref-qualifieropt exception-specificationopt -> type-id

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

Чуть позже еще некоторые изменения опишу.

Автор: Hryak 31.03.08, 18:54
Цитата Flex Ferrum @
На последнем заседании комитета по стандартизации среди всего прочего в стандарт C++0x включили поддержку lambda-функций.

Хорошая новость!
I :wub: λ...

Автор: Flex Ferrum 31.03.08, 18:57
Цитата Hryak @
Хорошая новость!

Надеюсь, не первоапрельская. :)

Автор: archimed7592 31.03.08, 22:03
Цитата Flex Ferrum @
в стандарт C++0x включили поддержку lambda-функций.

Yeehhhaaaaaa! :yes:



Цитата Flex Ferrum @
Также приняты в стандарт новый (альтернативный) формат объявления методов:
[...]
Т. е. позволяет задавать тип возвращаемого значения в конце объявления функции (что можно увидеть в приведенных выше фрагментах кода).

Если честно в выше приведённых фрагментах этого не заметил, но, правильно ли я понимаю, что теперь запись
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeClassThatHaveVeryVeryLongName::SomeInternalType SomeClassThatHaveVeryVeryLongName::someMethod(...)
    { }
можно будет заменить чем-то вроде
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeClassThatHaveVeryVeryLongName::someMethod(...) -> SomeInternalType
??



Цитата Flex Ferrum @
Также позволили в объявлении функции использовать auto вместо типа возвращаемого значения. В этом случае тип функции был определен по типу возвращаемго значения в "самом последнем" операторе return.

Прям не нарадуешься на новый Стандарт :).

Добавлено
Цитата Flex Ferrum @
Надеюсь, не первоапрельская. :)

:lol:

Автор: Flex Ferrum 31.03.08, 22:10
Цитата archimed7592 @
можно будет заменить чем-то вроде

SomeClassThatHaveVeryVeryLongName::someMethod(...) -> SomeInternalType

??

Видимо, да. Либо на
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto SomeClassThatHaveVeryVeryLongName::someMethod(...) {...}


Добавлено
Еще из интересных добавлений.

Наследование конструкторов
Т. е. можно будет писать:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Base
    {
    public:
       Base(T1, T2, T3, T4, T5, ...);
    };
     
    class Derived : public Base
    {
    public:
       using Base::Base; // Автоматически объявляет конструктор Derived::Derived(T1, T2, T3, T4, T5, ...);
    };


inline-пространства имен.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace Lib
    {
      inline namespace Lib_1
      {
        template <typename T> class A;
      }
     
      template <typename T> void g(T);
    }
    ...
    struct MyClass { ... };
    namespace Lib
    {
      template<> class A<MyClass> { ... };
    }
     
    int main()
    {
      Lib::A<MyClass> a;
      g(a);  // ok, Lib is an associated namespace of A
    }

Подробности здесь: http://www.open-std.org/jtc1/sc22/wg21/doc.../2008/n2535.htm

В библиотеку STL добавлены односвязные списки
(думаю, в пояснениях не нуждается)

(не менее вкусное!!!)
C членов union-ов сняты все ограничения кроме одного - они не могут быть ссылочного типа!!!!
Иными словами, теперь в union'ах можно объявлять члены любого типа, в том числе имеющего нетривиальные конструкторы и деструкторы. Вся ответственность, понятное дело, лежит на программисте. Но, как написано в соответствующем proposal, "union'ы - они такие от рождения". :)
Правда, в этом случае все методы, которые для классов могут быть автосгенерированы самим компилятором по новому стандарту обозначаются как deleted-члены. Таким образом, на программиста ложится работа по явному объявлению и определению конструкторов/деструкторов/операторов присваивания для такого рода объединений. Теперь создание вариантных типов становится задачей практически тривиальной... :)

Ключевое слово auto окончательно разжаловано и из storage-class спецификаторов
Думаю, в комментариях тоже не нуждается. :) auto переквалифицировалось в автоопределение типа... :)

Вложенные исключения
В STL введен новый тип исключения - std::nested_exception, позволяющий оборачивать исключения одно в другое.

Автор: Cechmanek 28.04.08, 08:32
Flex Ferrum
Цитата

На последнем заседании комитета по стандартизации среди всего прочего в стандарт C++0x включили поддержку lambda-функций. Полное описание можно прочитать в статье. Вкратце, новый стандарт будет допускать следующий код:
Вывод коллекции на консоль:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Writing a collection to cout, in today's C++, option 2:
     
    copy( w.begin(), w.end(),
              ostream_iterator<const Widget>( cout, " " ) );
     
     
    // Writing a collection to cout, in C++0x:
     
    for_each( w.begin(), w.end(),
                    []( const Widget& w ) { cout << w << " "; } );


Что за скобки [] перед (const Widget) ? Что они означают ?

Автор: Hryak 28.04.08, 09:03
Цитата Cechmanek @
то за скобки [] перед (const Widget) ? Что они означают ?

Означают то, что за ними располагается определение ламбда-функции.

Автор: Cechmanek 28.04.08, 09:36
хм ... очень интересное решение.

Автор: Flex Ferrum 06.05.08, 06:02
Для желающих попробовать некоторые фишки стандарта уже сейчас, gcc 4.3 под винду можно залить отсюда:
http://www.tdragon.net/recentgcc/

Автор: Flex Ferrum 06.05.08, 07:46
Проверено. Работает. :)

Автор: Flex Ferrum 07.05.08, 11:31
Текущее состояние предложений по изменениям в стандарте можно увидеть на этой странице:
State of C++ Evolution

Автор: Alek86 10.05.08, 09:06
не хочется долго рыскать по незнакомым докам, потому тут спрошу
собираются в новом стандарте изменить STL в более удобную сторону (как в бусте) - к примеру добавить возможность передавать в алгоритмы весь контейнер (чтобы не писать кажжый раз xx.begin(), xx.end() и иметь возможность вложенных вызовов)?

Автор: archimed7592 10.05.08, 12:51
Alek86
Library Evolution
Цитата

...
New Language Support Planned for C++0x
These propsals take advantage of some new language feature, either voted into the Core Language or anticipated for the Final Candidate Document.
...
N2245 Range Utilities for C++0x Thorsten Ottosen
...

New Library Components Planned for a Future TR
These papers present libraries that are actively under consideration for a future TR. The Library Working Group is committed to an ongoing process of TRs, adopting libraries 'when they are ready'. As such, there is no target TR number associated with any given proposal.
...
N1871 Range Library Proposal Thorsten Ottosen
N2068 Range Library Core Thorsten Ottosen
...

В общем я так и не понял, то ли range в TR включат, то ли в 14883...

Автор: archimed7592 30.09.08, 19:02
Цитата FireZilla @
Язык С++ имеет существенные огрехи

Ты считаешь, есть язык, не имеющий существенных огрехов? Я давно такой ищу...

Автор: FireZilla 30.09.08, 19:28
Нет я не считаю что языков без "огрехов" нет. Я считаю что комитет по стандартизации С++ занимается изобретением новых "закорлючек" вместо того чтобы исправить старые недостатики. Причем как раз эти "закрлючки" как раз и предназначены для обхода недостатков.

IMHO Типы вроде int8_fast и т.д. не испрявят ситуацию когда я всеравно могу написать long и на разных процессорах это будет либо 16 либо 32 либо 64 бита. Или нам всем дружно взятся и перерефакторить миллионы строк кода.

И вообще почитай примеры кода которые ты сам выложил в первом посте, если говорить совершенно откровенно если вдуматся то обявления вроде

typedef X::value_type value_type;
void push(X& x, value_type value ) { x. push_back(value); }
void pop(X& x) { x. pop_back(); }
T top(const X& x) { return x.back(); }

Не так уж и далеко от Brainfuck кода.

Автор: Flex Ferrum 30.09.08, 19:33
Цитата FireZilla @
Из-за остутвия finally приходится использовать смарты, которые добавляют к программе лишних 100-200 КБ кода, даже если в принципе нет особой нужды в подсчете ссылок и т.п.

Нет, это :lool: . Трижды. Активно программируя на шарпе (где используется этот самый try-finally) и на С++ (где его нет), лучше все же в С++. Типичная конструкция в шарпе:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
                OleDbDataReader r = null;
                try
                {
                    OleDbCommand cmd = new OleDbCommand(check_sql, m_Connection);
     
                    AddParameterInt(cmd, (int)ai.ID);
                    r = cmd.ExecuteReader();
                    if (r.Read())
                        UpdateIniniator(ai);
                    else
                        InsertInitiator(ai);
                }
                finally
                {
                    if (r != null)
                        r.Close();
                }

И так везде, где требуется контроль освобождения ресурсов при выходе из блока/функции. Или (о! небеса!) - использование для тех же целей using:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    using (OleDbDataReader r1 = null)
    {
       // ...
       using (OleDbDataReader r2 = null)
       {
          // ...
       }
    }

Хорошо, если переменных - одна-две. А если их три-пять?
Так что, за finally агитировать не надо.

Цитата FireZilla @
А теперь про то что не попало в стандарт и слава богу - свойства. Имея дело с делфи я пришел к выводу что подобная практика фактически бесполезна. Свойства легко реализуются через сетеры и гетеры (т.е функции) которые к томуже могут быть автоматичики сгенерированны ИДЕ.

Спорный тезис.

Добавлено
Цитата FireZilla @
IMHO Типы вроде int8_fast и т.д. не испрявят ситуацию когда я всеравно могу написать long и на разных процессорах это будет либо 16 либо 32 либо 64 бита. Или нам всем дружно взятся и перерефакторить миллионы строк кода.

И что? Ситуаций, когда нужны типы фиксированной длины - не так много. Точнее, они ограничиваются только наличием требований бинарной совместимости (серелизация/десерелизация данных). Все! В остальных случаях совершенно побарабану - сколько именно места занимает int или long. :)

Автор: archimed7592 30.09.08, 19:41
Цитата FireZilla @
вместо того чтобы исправить старые недостатики

Смотря что понимать под исправлениями. Breaking changes - это не совсем исправления. При появлении таковых бунт устроит намного большее число пользователей языка С++, чем тех, кто агиттировал за эти изменения.

Цитата FireZilla @
Или нам всем дружно взятся и перерефакторить миллионы строк кода.

Рефакторить не хочешь, но хочешь "исправления" старого кода(а что его исправлять? Если он старый, то он либо работает, либо он никому не нужен не работающий).

Цитата FireZilla @
И вообще почитай примеры кода которые ты сам выложил в первом посте, если говорить совершенно откровенно если вдуматся то обявления вроде

Я вот смотрю на приводимые тобою примеры и совсем не понимаю, что ты ими показать пытаешься...

Автор: Dantes 30.09.08, 20:32
Цитата archimed7592 @
Я вот смотрю на приводимые тобою примеры и совсем не понимаю, что ты ими показать пытаешься...

Учитывая, что в трех из них написан бред, а также судя по остальному тексту, можно предположить, что их автор - троль :whistle:

Автор: Hsilgos 30.09.08, 21:01
Я чё та прифигел... Неужели аффтар прав и здесь будет именно такой ответ?
Нет компилера под рукой, подскажите, а ?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class A {
      public:
        virtual void func() {
          std::cout<<"This is A class"<<std::endl;
        }
    };
    class B: public A {
       public:
         virtual void func() {
           std::cout<<"This is B class"<<std::endl;
         }
    };
     
    ...
     A a;
     a.funck();
     
     B b;
     b.funck();
     
      This is A class
      This is A class

Автор: Flex Ferrum 30.09.08, 21:07
Цитата Hsilgos @
Неужели аффтар прав и здесь будет именно такой ответ?

Нет, аффтар не прав. Он явно не проверял код перед отправкой поста. Как, впрочем, и в следующем примере. Код
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      bool validResult = false;
      int i = -1;
      while(!validResult)
      {
        i ++;
        switch(i)
        {
          case 0:
             break;
          case 1:
            break;
          case 2:
            break;
          case 3:
            validResult = 1;
            break;
        }
     
        std::cout << "i = " << i << ", validResult = " << validResult << std::endl;
      }
      std::cout << "Loop finished" << std::endl;


честно отрабатывает положенные 4 итерации. По этому с какого перепугу автор поста решил, что break внутри switch прерывает внешний цикл - известно только автору...

Автор: Hsilgos 30.09.08, 21:26
Ну с шаблонами - ладно, шаблоны это, можно сказать, отдельный подъязык в языке С++. (По моему скромному имхо, язык программирования должен стремиться к такому виду.)

Цитата
На последнем заседании комитета по стандартизации среди всего прочего в стандарт C++0x включили поддержку lambda-функций.

Лямбда функции тоже ничё, давно пора. Хотя для восприятия это будет сложновато.
И, думаю, будет рассадник копипаста у нерадивых программистов. И да... какая теперь разница будет между
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for_each( v.begin(), v.end(), []( Widget& w )
    {
      ...
      ... use or modify w ...
      ...
    } );


и
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for(iterator it = v.begin(),itEnd = v.end(); it != itEnd; ++it)
    {
       use or modify "*it";
    }

??? :D

Цитата
В библиотеку STL добавлены односвязные списки

Нафига? Меньше памяти?

Цитата
Также позволили в объявлении функции использовать auto вместо типа возвращаемого значения. В этом случае тип функции был определен по типу возвращаемго значения в "самом последнем" операторе return.

Ключевое слово auto будет только для шаблонов или в любом месте использоваться?
Для чего это вообще то нужно? Теперь при виде метода придется лезть внутр и смотреть, какой же тип возвращает функция... Да и тот будет выбираться из какого-то непонятного правила "последнего return". По-моему, это плохо. Убедите меня в обратном =))



Нда, я как посмотрю, язык С++ становится всё сложнее и сложнее. Владеть полностью С++ в будущем будет означать принадлежность к касте этаких тру-бородатых, заросших программистов в очках :D
У меня неоднозначное отношение к этому. Не приведет ли это к смерти языка, как очень сложного?

Добавлено
Цитата
Из-за остутвия finally приходится использовать смарты, которые добавляют к программе лишних 100-200 КБ кода, даже если в принципе нет особой нужды в подсчете ссылок и т.п.

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

Цитата
char a[1];
a[10] = 100;


Сам себе противоречишь. Хочешь, чтобы С++ небыл похож на С и в то же время используешь С-шные rконструкции.
vector + vector::at тебе в руки.

Автор: archimed7592 30.09.08, 21:40
Цитата Hsilgos @
И да... какая теперь разница будет между

Первый вариант более гибкий.
Цитата Hsilgos @
Ключевое слово auto будет только для шаблонов или в любом месте использоваться?

Ключевое слово auto имеет весьма посредственное отношение к шаблонам...
Цитата Hsilgos @
Для чего это вообще то нужно?

Для гибкости. Знаешь как в C# удобно пользоваться var?(IIRC, начиная с 3.0 появилось)
Цитата Hsilgos @
Теперь при виде метода придется лезть внутр и смотреть, какой же тип возвращает функция...

Это самое вкусное - концептуальное программирование. Ты не знаешь какого типа возвращённый тебе объект, но ты знаешь концепт, реализуемый этим объектом. Концепт - это такой контракт между библиотекой и её пользователем. К примеру, можно встретить в стандарте в описании STL(iterator requirements, sequence container requirements and so on), в бусте(threads, mutex, etc.). А с появлением валидируемых концептов в самом языке это перестаёт быть пустыми словами. Ещё большую гибкость предоставляют концепт-мапы, позволяющие создавать адаптеры от одного концепта к другому.

Автор: Flex Ferrum 30.09.08, 21:40
Цитата Hsilgos @
И да... какая теперь разница будет между

Кхм-кхм... Читаем на этой странице:
GCC 4.3.2 changes:
Цитата
An experimental parallel mode has been added. This is a parallel implementation of many C++ Standard library algorithms, like std::accumulate, std::for_each, std::transform, or std::sort, to give but four examples. These algorithms can be substituted for the normal (sequential) libstdc++ algorithms on a piecemeal basis, or all existing algorithms can be transformed via the -D_GLIBCXX_PARALLEL macro.

Теперь ответ на твой вопрос очевиден. ;)

Цитата Hsilgos @
И, думаю, будет рассадник копипаста у нерадивых программистов.

С одной стороны, да. С другой - открывает новые возможности. Вот тебе задачка. Тебе нужно протестировать как один класс работает с объектами другого класса - в правильном ли порядке методы вызываются и все такое. Если взаимодействие построено на базе интерфейсов, то тебе ничего не стоит написать такую реализацию класса, с которым производится взаимодействие, что она будет вызывать делегаты.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct ISomeInterface
    {
    public virtual void Foo1() = 0;
    public virtual void Foo2() = 0;
    public virtual void Foo3() = 0;
    };
    //...
    class TestClassThunk : public ISomeInterface
    {
    public:
    std::function<void ()> FuncDelegate;
     
    FuncDelegate OnFoo1;
    FuncDelegate OnFoo2;
    FuncDelegate OnFoo3;
     
    void Foo1() {OnFoo1();}
    void Foo2() {OnFoo2();}
    void Foo3() {OnFoo3();}
    };
     
    //...
     
    void TestSomething()
    {
       TesteeClass target;
     
       TestClassThunk tester;
     
       bool foo1_called = false;
       tester.OnFoo1 = []() {foo1_called = true;}
     
       target.SomeMethod(tester);
     
       assert(foo1_called);
    }

Существующими методами ты такое напишешь с бОльшим трудом. Без boost::lambda/boost::phoenix - так вообще никак.


Цитата Hsilgos @
Для чего это вообще то нужно?

Чтобы вместо:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::map<std::string, std::vector<int> >::const_iterator p = m_Map.begin();

писать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto p = m_Map.cbegin();

Автор: Hsilgos 30.09.08, 21:42
Цитата
typedef X::value_type value_type;
void push(X& x, value_type value ) { x. push_back(value); }
void pop(X& x) { x. pop_back(); }
T top(const X& x) { return x.back(); }

А чё, это нормально...
вот это больше на brainfuck похоже
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef return_type(T::*MemFun)(const arg_type& v1);
    return_type ret = (obj->*MemFun)(val);

:)

Автор: Flex Ferrum 30.09.08, 21:44
Цитата Hsilgos @
вот это больше на brainfuck похоже

Это еще не brainfuck...

Автор: archimed7592 30.09.08, 21:45
Цитата Flex Ferrum @
Кхм-кхм... Читаем на этой странице:
GCC 4.3.2 changes:

Мухаха, сколько же после этого сломается кода, который делал расчёт на порядок вызова функтора :rolleyes:.

Автор: Flex Ferrum 30.09.08, 21:52
Цитата archimed7592 @
Мухаха, сколько же после этого сломается кода, который делал расчёт на порядок вызова функтора :rolleyes:.

Ну, тут уж народ сами себе злобные буратинки... :)

Автор: Hsilgos 30.09.08, 21:52
Цитата Flex Ferrum @
Чтобы вместо:

std::map<std::string, std::vector<int> >::const_iterator p = m_Map.begin();


писать

auto p = m_Map.cbegin();

Хм. Значит ли это, что теперь абсолютно люой тип можно булет описать как auto?
Для таких задач хорошо использовался typedef

Цитата
Это еще не brainfuck

Ну для нас с тобой - нет. А вот я как-то видел выражения лица у человека, который пишет на C# при виде этого кода.
Он мне говорит, "Для меня это примерно каквот такой код #*&#HKkjh##@#" =)

Автор: Flex Ferrum 30.09.08, 21:53
Хотя, нередко std::accumulate используется именно для последовательной сцепки элементов. В паралельном режиме результат, гм... непредсказуем... :)

Добавлено
Цитата Hsilgos @
Значит ли это, что теперь абсолютно люой тип можно булет описать как auto?

Видимо.

Цитата Hsilgos @
Для таких задач хорошо использовался typedef

Ну, не всегда его использование полностью оправдано. Т. е. использовать typedef только для того, чтобы упростит текст программы (а не для введение нового псевдонима типа) - не есть гуд.

Автор: archimed7592 30.09.08, 22:04
Цитата Hsilgos @
Хм. Значит ли это, что теперь абсолютно люой тип можно булет описать как auto?

Что значит описать? auto - это вариант определиния переменной, аналогичный использованию deduced template parameter в аргументах ф-ции:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template< class T >
    void foo(const T &arg)
    {
       // ...
    }
Означает ли это, что абсолютно любой тип можно описать как T? ;)

Цитата Hsilgos @
Для таких задач хорошо использовался typedef

typedef менее гибкий. См. какую возможно даёт auto:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // представим, что у нас есть концепт string который обязывает
    // к наличию метода length() с соответствующей семантикой(и др. методов, ессно)
     
    // library code
    SomeLibrary::SomeStringImplementation getSomeValue();
     
    // client code
    auto value = getSomeValue();
     
    // год спустя вышла другая библиотека, предоставляющая намного более эффективную реализацию концепта string
     
    // library code
    YetAnotherLibrary::EffectiveStringImplementation getSomeValue();
     
    // client code
    auto value = getSomeValue(); // не меняется

Это предоставляет просто шикарные перспективы для проектирования чёрных ящиков за которыми, я считаю, будущее программирования.

Концепты, в свою очередь - это очень эффективный(хотя бы по той причине, что они compile time) аналог интерфейсов.

typedef, в свою очередь, придётся менять на стороне клиента.

При выходе новой версии библиотеки, с новыми концептами, старые можно будет обернуть в концепт-мапы тем самым сохранив backward compatibility.

Автор: Hsilgos 30.09.08, 22:06
Не стал копировать весь пример...
Цитата
bool foo1_called = false;
tester.OnFoo1 = []() {foo1_called = true;}

Это пример попахивает возвращением к глобальным переменным. :)
Но в принципе суть я уловил, своё применение фишка найдет, иногда такое ой как надо :)

Автор: archimed7592 30.09.08, 22:08
Цитата Hsilgos @
Это пример попахивает возвращением к глобальным переменным. :)

Это зависит от программиста и от того, как он воспользуется предоставляемыми инструментами.

Автор: Flex Ferrum 30.09.08, 22:13
Цитата Hsilgos @
Это пример попахивает возвращением к глобальным переменным.

Ну не скажи. Лямбды они тем и хороши, что могут работать в контексте инициализации функтора.

Автор: archimed7592 30.09.08, 22:15
Цитата Flex Ferrum @
Хотя, нередко std::accumulate используется именно для последовательной сцепки элементов. В паралельном режиме результат, гм... непредсказуем... :)

Вот это, к слову говоря, открывает одну палку С++ о двух концах. С одной стороны, стремление в С++ к минимализму, в принципе, мне понятно и чем-то изнутри меня это стремление одобряется. С другой стороны, крайность, с которой С++ проповедует минимализм меня немного ужасает. Вот взять std::string и QString - в первом всего по минимум, другим, OTOH, очень удобно пользоваться. Почему не сделают какой-никакой аналог интерфейса QString, .NET::System::String, etc.?
Аналогично с алгоритмами - почему нет строковых алгоритмов, в частности concatenate/join мне не совсем понятно... Его стоило бы ввести даже если бы для accumulate был бы специфицирован порядок аккумуляции по той простой причине, что я хочу сказать в коде "я объединяю коллекцию строк", а не "я аккумулирую коллекцию строк".

Автор: Hsilgos 30.09.08, 22:18
archimed7592
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // library code
    SomeLibrary1::SomeClassImplementation1 getSomeValue1();
    // library code
    SomeLibrary2::SomeClassImplementation2 getSomeValue2();
     
    // client code
    auto value1 = getSomeValue1();
    auto value2 = getSomeValue2();
     
    // ок. А теперь я хочу вызвать какие-то методы
    value1.SomeMethod1();
    value2.SomeMethod2();
    // Э... А как их различать? А как компилятор различает эти 2 разных типа?
    // А может, так?
    (SomeLibrary1::SomeClassImplementation1)value1.SomeMethod1();
    (SomeLibrary1::SomeClassImplementation1)value2.SomeMethod2();
    //  Фуууууу....

Автор: Flex Ferrum 30.09.08, 22:21
Цитата archimed7592 @
Его стоило бы ввести даже если бы для accumulate был бы специфицирован порядок аккумуляции по той простой причине, что я хочу сказать в коде "я объединяю коллекцию строк", а не "я аккумулирую коллекцию строк".

Ээээ...
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector<string> strings = ....;
     
    std::string result = boost::join(strings, "\\");

:whistle:
string_algo

Автор: Hsilgos 30.09.08, 22:35
И вообще, я такой код уже где-то видел.
Э... Дай мне мой маразм памяти...
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    10 DEM i1 = 12;
    20 DEM i2 = 'Hello'
    30 Print i2;
    40 Print i1;
    50 goto 10

Как-то так :D

Автор: Flex Ferrum 30.09.08, 22:38
Цитата Hsilgos @
И вообще, я такой код уже где-то видел.
Э... Дай мне мой маразм памяти...

Правда, тут нужно учесть разницу между compile-time и run-time типизацией. ;)

Автор: archimed7592 01.10.08, 00:19
Цитата Flex Ferrum @
Ээээ...

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


Hsilgos, либо я тебя не понимаю, либо ты меня. Третьего не дано :).
Цитата Hsilgos @
// Э... А как их различать? А как компилятор различает эти 2 разных типа?

Вот зачем ему что-то различать? Он и так знает какого типа переменная...

Опять же, провожу аналогию с шаблонными ф-циями:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // library code
    template< class StringT >
    void foo(const StringT &str)
    {
        int len = str.length(); // как он различает? А может так: ... Фyyyyуу
        std::cout << "passed string length equals to " << len << std::endl;
        // ...
    }
     
    // client code
    std::string ss = "standard string";
    QString qs = "qt string";
    foo(ss);
    foo(qs);

Ты давно пользуешься тем свойством компилятора, что он всегда знает статические типы переменных(по крайней мере язык так устроен, что он не может не знать) просто, видимо, не до конца осознаёшь этого...

Автор: Flex Ferrum 01.10.08, 07:56
Цитата archimed7592 @
Ээээ, это буст, я про стандартную библиотеку. Почему нет в стандарте - одному комитету известно...

Тебе шашечки или ехать? ;)

Автор: archimed7592 01.10.08, 08:02
Цитата Flex Ferrum @
Тебе шашечки или ехать? ;)

Мне бы скрестить наилучшии стороны C++, Java и C#, включая их фреймворки :).

Автор: Flex Ferrum 01.10.08, 08:07
Цитата archimed7592 @
Мне бы скрестить наилучшии стороны C++, Java и C#, включая их фреймворки :).

О как... :) ИМХО, это из области фантастики... :)

Автор: archimed7592 01.10.08, 08:07
Цитата Flex Ferrum @
ИМХО, это из области фантастики... :)

Это ещё почему? :)

Автор: Flex Ferrum 01.10.08, 08:10
Цитата archimed7592 @
Это ещё почему? :)

Концепции слишком сильно различаются. Я думаю, например, что если бы было возможно перенести плюсовые шаблоны в шарп - это было бы сделано, но вместо этого там какие-то generic'и... И это, вообщем то, объяснимо. Тот же reflection накладывает свои ограничения. Ну и т. д.

Автор: archimed7592 01.10.08, 08:14
Цитата Flex Ferrum @
Концепции слишком сильно различаются. Я думаю, например, что если бы было возможно перенести плюсовые шаблоны в шарп - это было бы сделано, но вместо этого там какие-то generic'и... И это, вообщем то, объяснимо. Тот же reflection накладывает свои ограничения. Ну и т. д.

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

Добавлено
Цитата Flex Ferrum @
Концепции слишком сильно различаются.

BTW, я это отлично понимаю, но у меня в голове уже некоторое время крутится идея как эти концепции скрестить для получения более эффективной.

Автор: Flex Ferrum 01.10.08, 08:29
Цитата archimed7592 @
Флекс, я вот, хоть убей, никак не пойму, что мешает шаблонам жить рядом с дженериками, рефлексивным классам рядом с нерефлексивными, управляемой куче и неуправляемой, множественному наследованию и интерфейсам и т.д...

Судя по всему, технически это совместить очень сложно.

Автор: archimed7592 01.10.08, 08:34
Цитата Flex Ferrum @
Судя по всему, технически это совместить очень сложно.

Флекс, ну у тебя же на компьютере нормально сосуществует куча нативного кода и ява/дотнеты-машины?
Кстати, managed C++ - совмещено? Совмещено... Просто плохо и неудобно совмещено(по понятным причинам - целью было добится какой-нибудь совместимости, а ценою чего эта совместимость достанется никого, видимо, не волновало).

Автор: FireZilla 01.10.08, 10:45
Цитата Flex Ferrum @
Цитата FireZilla @
Из-за остутвия finally приходится использовать смарты, которые добавляют к программе лишних 100-200 КБ кода, даже если в принципе нет особой нужды в подсчете ссылок и т.п.

Нет, это :lool: . Трижды. Активно программируя на шарпе (где используется этот самый try-finally) и на С++ (где его нет), лучше все же в С++. Типичная конструкция в шарпе:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
                OleDbDataReader r = null;
                try
                {
                    OleDbCommand cmd = new OleDbCommand(check_sql, m_Connection);
     
                    AddParameterInt(cmd, (int)ai.ID);
                    r = cmd.ExecuteReader();
                    if (r.Read())
                        UpdateIniniator(ai);
                    else
                        InsertInitiator(ai);
                }
                finally
                {
                    if (r != null)
                        r.Close();
                }

И так везде, где требуется контроль освобождения ресурсов при выходе из блока/функции. Или (о! небеса!) - использование для тех же целей using:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    using (OleDbDataReader r1 = null)
    {
       // ...
       using (OleDbDataReader r2 = null)
       {
          // ...
       }
    }

Хорошо, если переменных - одна-две. А если их три-пять?
Так что, за finally агитировать не надо.

Цитата FireZilla @
А теперь про то что не попало в стандарт и слава богу - свойства. Имея дело с делфи я пришел к выводу что подобная практика фактически бесполезна. Свойства легко реализуются через сетеры и гетеры (т.е функции) которые к томуже могут быть автоматичики сгенерированны ИДЕ.

Спорный тезис.

Добавлено
Цитата FireZilla @
IMHO Типы вроде int8_fast и т.д. не испрявят ситуацию когда я всеравно могу написать long и на разных процессорах это будет либо 16 либо 32 либо 64 бита. Или нам всем дружно взятся и перерефакторить миллионы строк кода.

И что? Ситуаций, когда нужны типы фиксированной длины - не так много. Точнее, они ограничиваются только наличием требований бинарной совместимости (серелизация/десерелизация данных). Все! В остальных случаях совершенно побарабану - сколько именно места занимает int или long. :)

Мда, все это хорошо если ты программируеш единственный инструмент - Микропроцессор архитектуры Intel.
Нашему же вниманию предлагается международный стандарт на язык программирования для любого типа процессоров и контроллеров.

И вообще у меня сложилось впечатление что комитет стандартизирует не язык программирования, а собсвенно компилятор фирмы Intel. Язык как то начинает быть похожим на ассемблер intel. По всей видимости борьба с коррупцией набриает обороты, броремся так что даже американцы стали берать взятки :)

А касательно finally я скажу просто, если у меня всего одна переменная, зачем тогда мне прибавлять к программе хеадер с 5 000 строк кода :wall:

А про то что по барабану какой длинны тип данных, это ты загнул. Можно подумать инеграция кода написанного на разных языках, сетьвая передача данных, обмен данными с БД и вообще допустим проверка установки 3-го бита в 1 некоторой переменной просто улитучились из нашей жизни.

Автор: Flex Ferrum 01.10.08, 10:56
Цитата FireZilla @
Мда, все это хорошо если ты программируеш единственный инструмент - Микропроцессор архитектуры Intel.
Нашему же вниманию предлагается международный стандарт на язык программирования для любого типа процессоров и контроллеров.

Как бы так сказать, за свою практику я программировал не только Intel, и не только под Windows. А потому возможные проблемы с разным размером типов на разных архитектурах хорошо себе представляю.

Автор: D_KEY 01.10.08, 11:19
Цитата FireZilla @
И вообще у меня сложилось впечатление что комитет стандартизирует не язык программирования, а собсвенно компилятор фирмы Intel. Язык как то начинает быть похожим на ассемблер intel. По всей видимости борьба с коррупцией набриает обороты, броремся так что даже американцы стали берать взятки :)

Ну что за глупости.
Конечно, типы гарантированной фиксированной длины были бы не лишними. В том же сетевом программировании это бы очень пригодилось. Но для этого нужны новые типы, а такие типы, как short, int, long специализировать нельзя. И это как раз касается программирования "для любого типа процессоров и контроллеров".

Если тебе так уж нужны типы фиксированной длины и хочется обойтись без препроцессора и дополнительных типов компиляторов/системы, то и сейчас можно создать соответствующий список типов и искать в нем тип нужного размера.

Господа, а вот по поводу auto вопрос, может кто знает, такой код будет работать?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template< typename T >
    class A {
    public:
        template< typename Ind >
        auto operator[]( Ind i )
        {
             return data[i];
        }
    private:
        T data;
    };

Автор: Flex Ferrum 01.10.08, 11:57
Цитата FireZilla @
А касательно finally я скажу просто, если у меня всего одна переменная, зачем тогда мне прибавлять к программе хеадер с 5 000 строк кода

Ну, если у тебя всего одна переменная - то проконтролировать ее время жизни и без finally можно.

Автор: archimed7592 01.10.08, 14:16
Цитата D_KEY @
Господа, а вот по поводу auto вопрос, может кто знает, такой код будет работать?

Думаю, да... Почему бы и нет? Ведь на момент инстанцирования компилятор будет знать тип шаблонного аргумента :).

Автор: D_KEY 02.10.08, 08:47
Цитата archimed7592 @
Цитата D_KEY @
Господа, а вот по поводу auto вопрос, может кто знает, такой код будет работать?

Думаю, да... Почему бы и нет? Ведь на момент инстанцирования компилятор будет знать тип шаблонного аргумента :).

Да я тоже так "думаю", а вот найти инфу по этому вопросу не могу. Хотя и ищу из рук вон плохо ;)

Автор: Flex Ferrum 02.10.08, 08:50
Цитата archimed7592 @
Кстати, managed C++ - совмещено? Совмещено... Просто плохо и неудобно совмещено

Совмещено? :blink: :blink: Как же, ага. :) Я как-то попробовал в managed-коде (на MC++) попользоваться шаблонами. Получил по рукам от компилятора, и (в итоге) забросил это дело. Вот так вот оно совмещено было. ;)

Автор: Qraizer 02.10.08, 09:01
А скажите на милось, кто драфт читал, в файловые потоки ввели что-нибудь, позволяющие прицепить поток к уже открытому файлу? Бо уже достало писать что-то вроде
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      HANDLE   file1;
      filebuf  inFile1;
      int      handle1;
     
      file1=CreateFile(pat.second.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL,
                       OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
      if(file1==INVALID_HANDLE_VALUE)
      {
       DWORD errCode=GetLastError();
     
       errors.push_back(std::make_pair(errCode, pat.second));
       return;
      }
      inFile1.open(handle1=_open_osfhandle(reinterpret_cast<int>(file1), _O_RDONLY),
                   std::ios::binary | std::ios::in);
      if(!inFile1.is_open())
      {
       DWORD errCode=GetLastError();
     
       if(handle1==-1) CloseHandle(file1);
        else _close(handle1);
       errors.push_back(std::make_pair(errCode, pat.second));
       return;
      }
      inFile1.pubsetbuf(&buffer1[0], buffer1.capacity());
     
      /* ... */
      if(std::equal(std::istreambuf_iterator<char>(&inFile1), std::istreambuf_iterator<char>(),
                    std::istreambuf_iterator<char>(&inFile2))) break;
      /* ... */
     
      inFile1.close();
      _close(handle1);
и то спасибо MSу и STLPort-у.

Автор: Flex Ferrum 02.10.08, 09:11
Qraizer, а можешь сказать - в каких случаях вообще такое может понадобиться? Мне как-то всегда хватало ifstream/ofstream...

Автор: archimed7592 02.10.08, 09:11
Цитата D_KEY @
Да я тоже так "думаю", а вот найти инфу по этому вопросу не могу. Хотя и ищу из рук вон плохо ;)

Цитата 8.3.5/12
A late-specified return type is most useful for a type that would be more complicated to specify before the
declarator-id:
template <class T, class U> auto add(T t, U u) -> decltype(t + u);
rather than
template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);


Цитата Flex Ferrum @
Получил по рукам от компилятора, и (в итоге) забросил это дело. Вот так вот оно совмещено было. ;)

Всё там отлично пользуется. Другой вопрос, что эти шаблоны не видны из managed кода других сборок(из того же C#) - вот это, да, кривизна совмещения, но, как я уже отметил
Цитата archimed7592 @
по понятным причинам - целью было добится какой-нибудь совместимости, а ценою чего эта совместимость достанется никого, видимо, не волновало


Цитата Qraizer @
позволяющие прицепить поток к уже открытому файлу?

Что ты подразумеваешь под прицеплением потока к уже открытому файлу? (сорри, код я "слегка" не понял)

Автор: Flex Ferrum 02.10.08, 09:14
Цитата archimed7592 @
Всё там отлично пользуется. Другой вопрос, что эти шаблоны не видны из managed кода других сборок

Я имел ввиду Managed C++. А ты, видимо, говоришь про C++/CLI.

Добавлено
Цитата archimed7592 @
Что ты подразумеваешь под прицеплением потока к уже открытому файлу? (сорри, код я "слегка" не понял)

Ну в том смысле, что есть системных хендл открытого файла, и с ним надо ассоциировать STL-ныпоток.

Автор: archimed7592 02.10.08, 09:24
Цитата Flex Ferrum @
Я имел ввиду Managed C++. А ты, видимо, говоришь про C++/CLI.

Ммм... мне казалось, что это одно и то же... Разве нет?
По крайней мере в студии у меня только один вариант создания .NET/C++ проекта :).

Цитата Flex Ferrum @
Ну в том смысле, что есть системных хендл открытого файла, и с ним надо ассоциировать STL-ныпоток.

Дык, нехрен симстемными хэндлами вообще оперировать - тогда и цеплять ничего никуда не понадобится :).

Автор: Flex Ferrum 02.10.08, 09:26
Цитата archimed7592 @
Ммм... мне казалось, что это одно и то же... Разве нет?

Нет. Managed C++ - это первая инкарнация, которая была в 2003-ей студии. C++/CLI - это "с учетом недоработок и недоделок", а по сути - совсем другая реализация.

Автор: archimed7592 02.10.08, 09:28
Цитата Flex Ferrum @
Нет. Managed C++ - это первая инкарнация, которая была в 2003-ей студии. C++/CLI - это "с учетом недоработок и недоделок", а по сути - совсем другая реализация.

Ааа... А я всегда думал, что это два разных названия одного и того же. Не, первую инкарнацию я видел, но юзать побоялся :).
Суть моего высказывания не меняется - замени manager C++ на C++/CLI :).
BTW, на С++/CLI чуть ли не стандарт есть(или готовится), если я не ошибаюсь.

Автор: Qraizer 02.10.08, 12:23
Цитата archimed7592 @
Дык, нехрен симстемными хэндлами вообще оперировать - тогда и цеплять ничего никуда не понадобится
А приходится иногда. В приведённом примере, впрочем, это неактуально. Поток тут хорош был тем, что STLPort для бинарно открытого файла заюзывает memory-mapped, плюс бинарное сравнение файлов элементарным алгоритмом std::equal. Ну а файл открывался виндой всего лишь ради ключика FILE_FLAG_SEQUENTIAL_SCAN. Но вот понадобиться мне кастомный security descriptor присобачить, на пример в сервисе... Всё, STL побоку по-любому.

Автор: Flex Ferrum 28.10.08, 14:42
Хех. Кто хочет попробовать новые фишки стандарта в исполнении от Microsoft - качайте Microsoft Visual Studio 2010 Community Technology Preview. Обещают лямбды, auto, static assert. Более детальной информации по нововведениям пока найти не могу.

Добавлено
Эээ... Забыл предупредить. Качать придется от половины до семи гигов, т. к. CTP идет в виде образа для Virtual PC. :)

Автор: Flex Ferrum 28.10.08, 17:26
Собственно, в соседней теме подсказали источник подробностей:
http://blogs.msdn.com/vcblog/archive/2008/...c10-part-1.aspx

Автор: Flex Ferrum 29.10.08, 17:41
Кстати, по поводу лямбд в gcc. На самом деле, уже не так плохо:
Цитата

1. Lambda expressions can be passed to function templates, and are usable with the std::CallableN class of concepts.
2. A lambda function can be defined wherever a primary-expression is expected.
3. Default capture allows a lambda function to use external variables without first declaring them. An equals sign (=) means to store such captures by-copy; an ampersand (&) means by-reference.
4. However, each capture and its storage mechanism may be explicitly declared. In this context, an unadorned name means by-copy; an ampersand (&) means by-reference.
5. Initializer expressions, an extension to the proposal, are supported.
6. Argument types must be explicitly annotated.
7. The body must be a compound-statement.

Additional features include:

* When used inside a member function, a lambda
o can capture this explicitly, or by default when it uses direct or indirect references to class members.
o has private access to the class.

Bugs

* Return type deduction is currently broken.
* Although they can appear within templates, lambda functions may not be used with dependent types.


Взято отсюда:
http://parasol.tamu.edu/groups/pttlgroup/lambda/

Автор: maggot 30.10.08, 18:51
Цитата
It has been suggested to (re)use the keyword typedef—as done in the
paper [4] —to introduce template aliases:
template<class T>
typedef std::vector<T, MyAllocator<T> > Vec;
That notation has the advantage of using a keyword already known to introduce
a type alias. However, it also displays several disavantages among
which the confusion of using a keyword known to introduce an alias for
a type-name in a context where the alias does not designate a type, but
a template; Vec is not an alias for a type, and should not be taken for a
typedef-name. The name Vec is a name for the family std::vector<􀀀 ,
MyAllocator<􀀀 > > – where the bullet is a placeholder for a type-name.
Consequently we do not propose the “typedef” syntax.
On the other hand the sentence
template<class T>
using Vec = std::vector<T, MyAllocator<T> >;
can be read/interpreted as: from now on, I'll be using Vec<T> as a synonym
for std::vector<T, MyAllocator<T> >. With that reading, the new
syntax for aliasing seems reasonably logical.


Кто-нибудь может на пальцах объяснить, чем Алиасы лучше typedef templates?

Автор: archimed7592 31.10.08, 00:07
Цитата maggot @
Кто-нибудь может на пальцах объяснить, чем Алиасы лучше typedef templates?

Ummm... В приведённой тобой цитате "лучше" и "хуже" они только в плане "читабельности". В остальном они эквивалентны.

Автор: n0rd 12.11.08, 19:48
Доклад про Concepts. 1 час видео.

Автор: gpd 21.11.08, 09:58
Вам не кажется, что новым стандартом никто не будет пользоваться? Что язык будет слишком сложный? То есть для него никогда не будут созданы средства рефакторинга, анализа кода. Время обучения языку гараздо выше чем у многих других ныне популярных языков. Кому это нужно? Ведь на Java или С можно делать всё то же самое. Такое чувство, что новый стандарт приведет к тому, что C++0x будет чисто академическим языком. По-моему двигаться нужно в сторону упрощения языка, а не усложнения. Я лет 5 назад был сторонником С++ и думал что у него есть будущее. Но похоже с новым стандартом на С++ можно положить крест.

Автор: Qraizer 21.11.08, 13:28
Мне не кажется. Кое-что из нового жду с нетерпением, те же концепты, r-value ссылки и auto, к примеру. Думаю, что на осиливание нового в языке уйдёт порядка месяца, нового в библиотеке - раза в 2-3 больше. Это с учётом того, что boost в общем-то знаком. Так что лично для себя не вижу проблем. Сильно сложнее он в новом стандарте не становится, а вот удобнее становится заметно.

Автор: kanes 21.11.08, 13:31
Цитата Qraizer @
auto

А это который раньше в Си был или я что-то путаю? :wacko:

Автор: Dantes 21.11.08, 13:43
Цитата gpd @
Вам не кажется, что новым стандартом никто не будет пользоваться?

Забавное предположение :D

Цитата gpd @
Ведь на Java или С можно делать всё то же самое.

Нет, нельзя.

Цитата gpd @
По-моему двигаться нужно в сторону упрощения языка, а не усложнения.

За счёт усложнения языка достигается упрощение программирования. Упрощение языка приведёт к обратному эффекту.

Цитата gpd @
Я лет 5 назад был сторонником С++ и думал что у него есть будущее. Но похоже с новым стандартом на С++ можно положить крест.

К счастью, C++ не нуждается в таких сторонниках :lol: Гораздо выгоднее изучить сложную технологию, чем постоянно самостоятельно возиться над решением мелких проблем, тривиально решаемых с помощью этой технологии. Полагаю, всему прогрессивному человечеству данная прописная истина должна быть хорошо известна.

Автор: Qraizer 21.11.08, 14:21
kanes, ну, как бы да, но в новом стандарте auto из пешки превращается... если не в ферзя, то в ладью точно.
Dantes, как-то резко ты в конце... Или мне показалось?

Автор: kanes 21.11.08, 14:23
Цитата Qraizer @
ну, как бы да, но в новом стандарте auto из пешки превращается... если не в ферзя, то в ладью точно.

А можно по подробней об этом? Пожалуйста :)

Автор: archimed7592 21.11.08, 14:27
Цитата kanes @
А можно по подробней об этом? Пожалуйста

Первый пост, поиск по предложению
Цитата
Deducing the type of variable from its initializer expression.


Добавлено
Аналог var из C#(или var в C# - аналог auto :)).

Автор: miksayer 21.11.08, 16:09
Цитата archimed7592 @
Аналог var из C#(или var в C# - аналог auto ).

а для тех, кто не знает C# можно поподробнее?

Автор: kanes 21.11.08, 16:25
Переменная, определённая под этим ключевым словом автоматически приобретёт тип при инциализации. Если я правильно понимаю новый смысл auto

Добавлено
Например:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto y = 10.0;      // y — это число с плавающей точкой
    const auto *p = &y; // p является const double *

Автор: archimed7592 21.11.08, 16:33
Цитата miksayer @
а для тех, кто не знает C# можно поподробнее?

Скорее для тех, кто ленится прочитать уже не один раз написанное(в этой теме).
Ок. Было:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeNamespace::WithInnerNamespace::SomeVeryLongTypeName *obj = new SomeNamespace::WithInnerNamespace::SomeVeryLongTypeName();

Стало:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto *obj = new SomeNamespace::WithInnerNamespace::SomeVeryLongTypeName();

Это, на самом деле, самый примитивный случай.
Более интересные ситуации не решаемы копипастом.

Автор: amk 21.11.08, 18:40
В-общем, auto позволит в некоторых случаях сократить количество набиваемых символов, вместо
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    &
    for (std::vector<SomeType>::iterator i = myvector.begin(); i != myvector.end(); ++i) {
      ...
    }
можно будет написать более короткое
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for (auto i = myvector.begin(); i != myvector.end(); ++i) {
      ...
    }
А какого еще типа может быть i?

Вдобавок, позволит повысить гибкость шаблонов. Не обязательно будет так длинно описывать каждый возвращаемый тип (Точнее можно будет использовать не так строго определенные классы)

ИМХО, очень полезное изменение.

Автор: Qraizer 21.11.08, 19:04
Вот один из очень таких интересных случаев:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <complex>
     
    template <typename L, typename R>
    std::complex<decltype(L()+R())> operator+(const std::complex<L>& l, const std::complex<R>& r)
    {
     auto re = l.real()+r.real();
     auto im = l.imag()+r.imag();
     
     return std::complex<decltype(re)>(re, im);
    }

Автор: max_f 21.11.08, 21:42
А пересылку в шаблонах можно будет делать?
Если упрощенно, то что-нибудь такое:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template< typename T >
    class A {
    public:
        auto f()
        {
            return a.g();
        }
     
    private:
        T a;
     
    }; // class A

А то сейчас подобного поведения добиться вообще никак нельзя(или я пока слабоват в метапрограмминге).

Автор: trainer 23.11.08, 07:01
Одно из предполагаемых предназначений auto - определение типа результата функции на основании типа аргумента return. Правда неясен вопрос с несколькими return в функции, из-за чего эта возможность может быть и не включена.

Автор: Flex Ferrum 23.11.08, 12:24
Цитата trainer @
Правда неясен вопрос с несколькими return в функции, из-за чего эта возможность может быть и не включена.

Вполне может разруливаться путем ошибки компиляции. Т. е. компилятор потребует от программиста привести все return'ы к одному типу.

Автор: Dantes 23.11.08, 15:10
Цитата Flex Ferrum @
Т. е. компилятор потребует от программиста привести все return'ы к одному типу.

Возможно и менее строгое требование - существование общего типа, как у операндов тернарного оператора

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f(bool b)
    {
        if (b)
            return 1;
        else
            return 2.5;
     
        // поведение аналогично return b ? 1 : 2.5;
    }

Автор: amk 24.11.08, 17:34
Правда чтобы воспользоваться таким определением нужно видеть тело функции, то есть практически только для определения inline-функций и шаблонных.

Автор: D_KEY 24.11.08, 20:32
Цитата Dantes @
Цитата Flex Ferrum @
Т. е. компилятор потребует от программиста привести все return'ы к одному типу.

Возможно и менее строгое требование - существование общего типа, как у операндов тернарного оператора

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f(bool b)
    {
        if (b)
            return 1;
        else
            return 2.5;
     
        // поведение аналогично return b ? 1 : 2.5;
    }

Тип результата тернарного оператора определяется не "общем типом"(что это, кстати?), а типом последнего варианта...

Автор: Dantes 25.11.08, 11:14
Цитата D_KEY @
Тип результата тернарного оператора определяется не "общем типом"(что это, кстати?), а типом последнего варианта...

Тип его результата определяется правилами в пункте 5.16 стандарта. В стандарте нет термина common type, но такое словосочетание там присутствует, и что оно означает, по-моему, вполне очевидно.

Автор: slavik_xxx 03.12.08, 10:19
Да... Язык скатывается в яму маразма. Количества правил, крючков и их сочетаний увеличивается. Ясность чтения уменьшается.

Автор: D_KEY 06.12.08, 11:22
Цитата slavik_xxx @
Да... Язык скатывается в яму маразма. Количества правил, крючков и их сочетаний увеличивается. Ясность чтения уменьшается.

Фразы такого рода преследуют С++ с рождения ;) .
На мой взгляд язык становится даже проще в использовании и логичнее, а возможности его возрастают.
А если тебе не ясны какие-то "крючки" и "их сочетания" ты можешь их не использовать. "Что не использую, за то не плачу"...

Автор: Большой 08.12.08, 10:59
Цитата D_KEY @
"Что не использую, за то не плачу"...


с позиции практики, а с позиции теории. Ведь студентам тогда придется учить еще больше

Автор: Flex Ferrum 08.12.08, 11:06
Цитата Большой @
с позиции практики, а с позиции теории. Ведь студентам тогда придется учить еще больше

Хм. Боюсь, типичный студент несколько, гм, слабоват для изучения "теории" С++. По этому "больше" ему учить не придется.

Автор: Большой 08.12.08, 11:49
Меня просто радует вот эта фича

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto func(int x) -> double {return pow(x);}


т.е если раньше стандартом запрещено было создавать две функции с одинаковыми сигнатурами
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int func(int x);
    double func(int x);

так теперь все норма компилер сам будет соображать с auto(ну если компилер совсем будет слаб то ему подсунем, что тип возращаемого значения желательно double, наверное как и с inline он еще подумает делать его double или лучше int)
Интересно в новом стандарте эти 2 функции будут с разными сигнатурами или нет?

Автор: amk 08.12.08, 17:57
Сигнатура будет одна, и компилятор скорее всего не позволит тебе их создать.
Просто можно будет не указывать тип возврата. Компилятор сам сообразит. А типы параметров ты все равно укажешь.

Автор: Большой 09.12.08, 10:15
а когда ожидать пришествия нового стандарта?

Автор: B.V. 15.12.08, 08:03
Цитата Википедия
Комитет Стандартизации C++ намеревается опубликовать новый стандарт в 2009

Автор: Большой 18.12.08, 09:26
B.V.
Я слышал вроде бы в конце этого года комитет на Гаваях будет зажигать и только после этого будет принят новый стандарт.

Известно ли будет typeof в стандарте или нет?

Автор: LuckLess 18.12.08, 09:46
Цитата Большой @
Известно ли будет typeof в стандарте или нет?

насет typeof не знаю, но вот auto будет.. (а имхо auto - заменитель typeof..)

Автор: Большой 18.12.08, 09:51
Цитата LuckLess @
насет typeof не знаю, но вот auto будет..


Вычодит auto панацея от всех бед

Автор: archimed7592 18.12.08, 10:52
Цитата Большой @
Известно ли будет typeof в стандарте или нет?

Будет, только название "другое" будет иметь: decltype(...). В "длинных" постах в этой теме всё написано ;).

Автор: Большой 18.12.08, 16:32
archimed7592

мне кажется запомнить лучше typeof чем decltype
decltype сокращение от declaration type или нет?

Автор: archimed7592 19.12.08, 02:47
Цитата Большой @
мне кажется запомнить лучше typeof чем decltype

Насчёт лучше - сомневаюсь. Насчёт проще запомнить - ну, возможно.

Цитата Большой @
decltype сокращение от declaration type или нет?

Именно.

Автор: Qraizer 19.12.08, 14:16
Думаю, что "переименование" typeof в decltype вызвано отсутствием желания сделать кучу реализаций, которые поддерживали typeof как расширение языка, несовместимыми с новым стандартом. Кроме того, семантика decltype всё-таки чуток отличается от семантики typeof, или я не прав?

Автор: archimed7592 19.12.08, 14:30
Цитата Qraizer @
Кроме того, семантика decltype всё-таки чуток отличается от семантики typeof, или я не прав?

Для начала нужно определиться с тем, что мы понимаем под "семантикой typeof", тогда можно будет поговорить об отличиях от семантики decltype :).

Цитата Qraizer @
Думаю, что "переименование" typeof в decltype вызвано отсутствием желания сделать кучу реализаций, которые поддерживали typeof как расширение языка, несовместимыми с новым стандартом.

Не знаю, в вопрос особо не вдавался, но очень частая причина заключается в том, что при именовании сущностей(и, в особенности, ключевых слов), дабы минимизировать количество сломанного кода, комитет пользуется гуглём. В нашем случае различие в количестве результатов на порядок(typeof(25000) vs decltype(2000)).

Автор: Qraizer 19.12.08, 15:10
Цитата archimed7592 @
Для начала нужно определиться с тем, что мы понимаем под "семантикой typeof", тогда можно будет поговорить об отличиях от семантики decltype .
А я и не знаю этого typeof-а. Слышал - да. Но то, что слышал не коррелирует с decltype. Вот и сделал вывод.

Автор: archimed7592 19.12.08, 15:50
Цитата Qraizer @
Но то, что слышал не коррелирует с decltype

Чего слышал то? :)

Автор: Qraizer 19.12.08, 16:24
Блин, трижды обновлял страничку в ответ на "сервер недоступен", получил три поста. :(
Ну, что typeof имеет семантику применения результата typedef. В новом же стандарте decltype имеет больше возможностей. Нет?

Автор: archimed7592 19.12.08, 16:36
Цитата Qraizer @
Ну, что typeof имеет семантику применения результата typedef. В новом же стандарте decltype имеет больше возможностей. Нет?

Хм... Т.е. с твоих слов, decltype можно применять где-то где нельзя применять результат typedef и/или семантика применения decltype где-то будет как-то отличаться от применения результата typedef... Можно увидеть примеры?

Автор: Qraizer 19.12.08, 17:08
Не, не то. Результатом typeof(expr) является тип результата выражения expr. И если typeof встречается где-то в программе, семантически это будет эквивалентным тому, как если бы где-то был записан typedef, который каким-нибудь идентификатором именует этот самый тип результата expr, а на месте typeof стоял этот самый идентификатор, ведённый typedef-ом. Я так считал. Но возможно, что считал неправильно, потому как не юзал никогда typeof из-за его непереносимости. Почитав же о decltype, я сложил мнение, что они неэквивалентны.

Автор: archimed7592 19.12.08, 18:23
Цитата Qraizer @
Почитав же о decltype, я сложил мнение, что они неэквивалентны.

В каком месте? Ну, можешь считать, что где-то появляется typedef с уникальным именем. Можешь считать, что просто вместо выражения typeof/decltype подставляется тип. Семантически разница в чем заключается?

Автор: Qraizer 20.12.08, 14:58
Цитата archimed7592 @
Семантически разница в чем заключается?
Ну так я об этом и спрашивал. "Всё что знал, всё сказал" ©, а дальше был вопрос
Цитата Qraizer @
Кроме того, семантика decltype всё-таки чуток отличается от семантики typeof, или я не прав?
В драфте decltype описывается бо́льшим количеством пунктов.

Автор: archimed7592 20.12.08, 15:56
Цитата Qraizer @
Ну так я об этом и спрашивал. "Всё что знал, всё сказал" ©, а дальше был вопрос

Ну, в той степени, в которой ты раскрыл семантику typeof - нет, семантика decltype ничем не отличается :).

Автор: Большой 24.12.08, 06:02
David Vandevoorde and Nicolai M. Josuttis
Пишут о typeof следующее

При написании шаблонов часто полезно иметь возможность указать тип выражения,
зависящего от шаблона. Наглядным примером такой ситуации является объявление
арифметической операции для шаблона числового массива, в котором типы операндов
различны. Следующий пример должен прояснить данную мысль:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename Tl, typename T2>
    Array<???> operator+(Array<Tl>const& x, Array<T2>const& y);

Предположительно эта операция должна создать массив элементов, которые
являются результатом сложения соответствующих элементов массивов х и у. Таким образом,
результирующий элемент будет иметь тип х [0] +у [0]. К сожалению, в языке C++
отсутствует надежный способ выражения этого типа с помощью Т1 и Т2.
В качестве расширения, направленного на решение этого вопроса, в некоторых
компиляторах имеется операция typeof. Она напоминает операцию sizeof тем, что
позволяет получить из исходного выражения некоторый объект времени компиляции, но в
данном случае этот объект может выступать в качестве имени типа. Тогда предыдущий
пример можно записать следующим образом:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename Tl, typename T2>
    Array<typeof(Tl()+T2())> operator + (Array<Tl> const& x,
    Array<T2> const& y);

Очень даже неплохо, но не идеально. Действительно, здесь предполагается, что
данные типы могут быть инициализированы по умолчанию. Это можно обойти, вводя
вспомогательный шаблон.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename T>
    Т makeTO; // Определение не требуется
    template <typename Tl, typename T2>
    Array<typeof(makeT<Tl>()+makeT<T2>() ) >
    operator + (Array<Tl> const& x, Array<T2> const& y);

В аргументе typeof мы бы предпочли использовать х и у, но не можем этого сделать,
так как они не были объявлены в точке расположения конструкции typeof. Радикальное
решение этой проблемы заключается в том, чтобы ввести альтернативный синтаксис
объявления функции, в котором возвращаемый тип помещается после параметров.
// Шаблон функции оператора:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename Tl, typename T2>
    operator + (Array<Tl> constfc x, Array<T2> constfc y)
    -> Array< typeo f(x+y)>;

// Шаблон регулярной функции:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename Tl, typename T2>
    function exp(Array<Tl> const& x, Array<T2> const& y)
    -> Array<typeof(exp(x,y))>

Как видно из этого примера, новый синтаксис для неоператорных функций включает
новое ключевое слово, в данном случае— function (чтобы выполнить процесс
синтаксического анализа для операторных функций, достаточно ключевого слова operator).
Обратите внимание, что операция typeof должна быть операцией времени
компиляции. В частности, как видно из следующего примера, операция typeof не принимает
во внимание ковариантные возвращаемые типы.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Base {
    public:
    virtual Base clone();
    };
    class Derived : public Base {
    public:
    virtual Derived clone();
    // Ковариантный возвращаемый тип
    };
    void demo (Base* p, Base* q)
    {
    typeof(p->clone()) tmp = p->clone(); (
    // tmp всегда будет иметь тип Base
    }

Автор: Qraizer 24.12.08, 14:43
Большой, классная книжка. Я не видел другой, также подробно описывающей шаблоны.

Автор: Большой 06.01.09, 09:42
Известно,что в STL отсутствует алгоритм copy_if будет ли он в новом стандарте и вооще какие будут еще алгоритмы если будут конечно.

Автор: archimed7592 06.01.09, 09:46
Цитата Большой @
Известно,что в STL отсутствует алгоритм copy_if

Really? :)
Мне неизвестно :rolleyes:.
Посмотри на remove_copy_if. Думаю, это - как раз то, что ты понимаешь под copy_if.

Автор: Большой 06.01.09, 09:48
archimed7592
а вот мейерс утверждает, что нет

Автор: archimed7592 06.01.09, 10:12
Цитата Большой @
а вот мейерс утверждает, что нет

Извини, я не совсем понимаю, что именно он утверждает? То, что нет алгоритма копирования последовательности с заданным фильтром? Если да, то хотелось бы увидеть его слова дословно и в оригинале :rolleyes:.

Автор: Большой 06.01.09, 13:09
С. Мейерс
"Эффективное использование STL"
совет 36. Правильно используйте copy_if

В STL имеется 11 алгоритмов, в именах которых присутствует слово сору.
Но как ни странно, алгоритма copy_if среди них нет. Таким образом, вы можете вызывать replace_copy_if и remove_copy_if, к вашим услугам copy_backward и reverse_copy, но если вдруг потребуется просто скопировать элементы интервала, удовлетворяющие определенному предикату, вам придется действовать самостоятельно.

Добавлено
archimed7592
Хотя меня больше интересуют новые алгоритмы

Автор: archimed7592 06.01.09, 13:25
Большой, по поводу copy_if - смешно :). Непонятно, как это у Мейрса оказалось... Суть в том, что в STL отсутсвует великое множество алгоритмов, которые могли бы быть очень полезны(как copy_if, к примеру), но присутсвуют кирпичики из которых все эти полезные алгоритмы можно построить. Тот же copy_if который имеет ввиду Мейрс - это remove_copy_if с отрицанием предиката(я уверен, далее по тексту это упоминается).

Добавлено
Цитата Большой @
Хотя меня больше интересуют новые алгоритмы

Появились новые алгоритмы, модифицировались "старые"(в сторону поддержки концептов, rvalue references, intializers). Если интересуют подробности, то можешь скачать текущий черновик(который по сути является почти чистовиком) и сравнить с версией 2003 года. Версия 2003 года лежит в FAQ, последний черновик - на open-std.org. Раздел 25 Algorithms library.

Автор: Большой 15.01.09, 09:02
archimed7592
Да разобрался оказывается transorm общий случай копирования с условием.

А что такое Atomic operations library
и с чем его едят?

Автор: archimed7592 15.01.09, 13:38
Цитата Большой @
А что такое Atomic operations library
и с чем его едят?

Библиотека для совершения атомарных операций :).
Едят с многопоточностью.

Автор: Большой 15.01.09, 18:49
Цитата archimed7592 @
Едят с многопоточностью.

а как ?
мона небольшой пример.
плизззз

Автор: amatros 15.01.09, 21:03
Цитата Большой @
Цитата archimed7592 @
Едят с многопоточностью.

а как ?
мона небольшой пример.
плизззз

Вот и вот, прямо из кухни шеф-повара ;)

Автор: Большой 09.02.09, 13:25
Что-то в рабочем дравте не нашел Prohibited access specifier
Значит не будет?

Автор: Masterkent 09.02.09, 19:19
Цитата Большой @
Значит не будет?

Видимо, не будет. Будут deleted определения.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct X
    {
        X(X &) = delete;             // запрет на использование копирующего конструктора
        void operator =(X) = delete; // запрет на использование копирующего оператора присваивания
    };

Автор: Большой 18.02.09, 12:50
Masterkent
а default, что значит?

Автор: archimed7592 18.02.09, 14:45
Большой, см первый пост, поиск по заголовку "Defaulted and Deleted Functions". Или у тебя более конкретный вопрос есть?

Автор: Большой 19.02.09, 09:48
archimed7592
почитал совершенно непонятно. Единственное что понял, что default функции можно реализовывать как непосредственно в определении класса так и в не его.
Возможно default значит, что компилятор должен использовать "свои" версии функций обычно реализованные компилятором если пользователь их не определяет. Или это значит что-то иное?

Автор: archimed7592 19.02.09, 14:58
Большой, ну, к примеру, ты не хочешь модифицировать тело деструктора, но ты хочешь сделать его виртуальным:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct X
    {
        virtual ~X() = default;
    }


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

Дело в том, что если пользователь их не определяет, то компилятор и так воспользуется "своими" реализациями. Другое дело, когда пользователь их определяет - иногда, пользователю действительно необходимо определить свою версию деструктора(к примеру), но когда у него нет необходимости определять свой деструктор, а добавить виртуальность или изменить модификатор доступа(private/protected/public) хочется - тогда он может и сообщить компилятору о необходимых изменениях и оставить за компилятором реализацию по умолчанию.
К примеру, если есть желание сделать конструктор копирования protected, то можно увидеть разницу в количестве кода и потенциальной ошибке при добавлении новых полей и НЕредактировании конструктора:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // C++03
    struct X : B1, B2, ..., Bn
    {
        T1 f1;
        T2 f2;
        // ...
        Tn fn;
     
    protected:
        X(const X &copy)
            : B1(copy), B2(copy), ..., Bn(copy),
              f1(copy.f1), f2(copy.f2), ..., fn(copy.fn)
        { }
    }
     
    // C++09
    struct X : B1, B2, ..., Bn
    {
        T1 f1;
        T2 f2;
        // ...
        Tn fn;
     
    protected:
        X(const X &copy) = default;
    }

Заметь, при добавлении поля fn+1 или базового класса Bn+1 ничего редактировать в конструкторе не придётся.

Автор: Большой 19.02.09, 22:35
archimed7592
все равно не понятно а не проще тогда вообще не писать конструктор копирования (в этом случае компилер создаст свой конструктор копирования, работающего по принципу побитового копирования )

Автор: Flex Ferrum 19.02.09, 22:36
Цитата Большой @
все равно не понятно а не проще тогда вообще не писать конструктор копирования (в этом случае компилер создаст свой конструктор копирования, работающего по принципу побитового копирования )

Во-первых, не побитового, а поэлементного, а во-вторых - нет, не проще, т. к. в данном случае (если ты обратишь внимание) требование - чтобы конструктор бы protected. А компилятор по умолчанию сгенерирует public. Понятна разница?

Автор: Большой 19.02.09, 22:39
Цитата archimed7592 @
Большой, ну, к примеру, ты не хочешь модифицировать тело деструктора, но ты хочешь сделать его виртуальным:

с этим понятно, а с конструктором копий нет

Добавлено
Цитата Flex Ferrum @
Во-первых, не побитового, а поэлементного,

Саттер пишет что побитовое, а с конструктором копий понятно, не сразу обратил внимание на protected :)

Автор: archimed7592 19.02.09, 22:45
Цитата Большой @
с этим понятно, а с конструктором копий нет

Нужно, чтобы "конструктор копий" был protected.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A
    {
    };
     
    struct B
    {
    protected:
        B(const B &copy) = default;
    };
     
    int main()
    {
        A a1;
        A a2 = a1; // OK
     
        B b1;
        B b2 = b1; // error
    }

Понятно, что будет, если "вообще не писать конструктор копирования"?

Автор: Большой 19.02.09, 22:56
А если попробовать так?

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A
    {
    A(int _a) {}
    A()=default;
    };

будет работать?

Автор: archimed7592 19.02.09, 22:57
Цитата Большой @
будет работать?

Что именно?

Автор: Большой 19.02.09, 23:00
ну первый и второй конструктор

Автор: archimed7592 19.02.09, 23:03
Ну да. Кстати говоря - вот тебе ещё одно применение default.

Автор: Большой 19.02.09, 23:06
archimed7592
Вот об этом я и подумал, тогда очень хорошо

Автор: Большой 24.02.09, 07:09
а реализации адаптеров типа compose1 и compose2 реализованные в STL от SGI и ряда других.
Не будет?
Поискал в драфте ничего не нашел или не там искал?

Автор: Flex Ferrum 24.02.09, 07:17
Цитата Большой @
а реализации адаптеров типа compose1 и compose2 реализованные в STL от SGI и ряда других.
Не будет?

А зачем, если теперь будет bind?

Автор: Большой 24.02.09, 07:49
Flex Ferrum

Он полностью из boost
а всякие bind2sd для совместимости оставили?

Автор: Flex Ferrum 24.02.09, 07:52
Цитата Большой @
а всякие bind2sd для совместимости оставили?

Вроде да.

Автор: Большой 25.02.09, 11:39
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A { double x; };
    const A* a = new A();


Почему здесь type is double
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype(a->x) x3;


а здесь type is const double&
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype((a->x)) x4;


Добавлено
и в этом случае не разобрался
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);


что это?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype((*(T*)0) + (*(U*)0))

Автор: archimed7592 25.02.09, 14:15
Большой, ты о чём? Откуда эти выкладки? Ссылку хоть дай.

Автор: Masterkent 25.02.09, 15:19
Цитата Большой @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A { double x; };
    const A* a = new A();

Почему здесь type is double
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype(a->x) x3;

а здесь type is const double&
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype((a->x)) x4;

Существует разница между типом объявленной сущности и типом выражения, в котором эта сущность участвует. Также существует разница между типом возврата функции и типом выражения, представляющего собой вызов этой функции. Например, здесь

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int i;
    int &ri = i;
    int f();
    int &g();
    int &&h();
     
    struct A { int x; };
    const A* a = new A();
     
    decltype(i)       x1; // int    (i - id-expression)
    decltype((i))     x2; // int &
    decltype(ri)      x4; // int &  (ri - id-expression)
    decltype((ri))    x5; // int &
    decltype(f())     x6; // int    (f() - function call)
    decltype((f()))   x7; // int    (f() - function call)
    decltype(g())     x8; // int &  (g() - function call)
    decltype((g()))   x9; // int &  (g() - function call)
    decltype(h())    x10; // int && (h() - function call)
    decltype((h()))  x11; // int && (h() - function call)
    decltype(a->x)   x12; // int    (a->x - class member access)
    decltype((a->x)) x13; // const int &

тип объявленной сущности (переменной) i - это int, тип выражения i - это int,
тип объявленной сущности (ссылки) ri - int &, тип выражения ri - int,
тип возврата f - int, тип выражения f() - int,
тип возврата g - int &, тип выражения g() - int,
тип возврата h - int &&, тип выражения h() - int,
тип объявленной сущности A::x - int, тип выражения a->x - const int.

Помимо типа, у всякого выражения есть дополнительная характеристика - это принадлежность к lvalue или rvalue. Например, выражения i, ri и g() в примере выше - это lvalue, а f() и h() - это rvalue.

decltype даёт возможность выяснить как тип объявленной сущности или тип возврата функции, так и тип выражения вместе с принадлежностью его к lvalue или rvalue.

Если в качестве аргумента e указывается id-expression или class member access, то результат decltype(e) обозначает тип соответствующей объявленной сущности. При этом выражение e имеет тип std::remove_reference<decltype((e))>::type и является lvalue, если std::is_lvalue_reference<decltype((e))>::value равно true.

Если в качестве аргумента указывается вызов функции или вовлечение перегруженного оператора (круглые скобки вокруг будут игнорироваться), то результат decltype обозначает тип возврата функции, выбранной для вызова. При этом выражение e имеет тип std::remove_reference<decltype(e)>::type и является lvalue, если std::is_lvalue_reference<decltype(e)>::value равно true.

Обычно выяснять тип и принадлежность к lvalue поотдельности не требуется, т.е. результат decltype в большинстве случаев будет использоваться без каких-либо дополнительных манипуляций с ним.

Цитата Большой @
и в этом случае не разобрался
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);

что это?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    decltype((*(T*)0) + (*(U*)0))

Здесь определяется тип суммы двух слагаемых, одно из которых - lvalue типа T, а другое - lvalue типа U. При определении типа аргумента decltype учитываются типы и принадлежность к lvalue подвыражений, из которых он состоит (при этом сами подвыражения не вычисляются). Имеем:
выражение (T*)0 - rvalue типа T* (в данном случае принадлежность к lvalue/rvalue ни на что не влияет),
выражение *(T*)0 - lvalue типа T
выражение (U*)0 - rvalue типа U* (в данном случае принадлежность к lvalue/rvalue ни на что не влияет),
выражение *(U*)0 - lvalue типа U
выражение (*(T*)0) + (*(U*)0) имеет тот же тип и ту же принадлежность к lvalue/rvalue, что и t + u.

Добавлено
Цитата archimed7592 @
Откуда эти выкладки?

Видимо, из черновика стандарта:

Цитата N2798 7.1.6.2 Simple type specifiers / 4
The type denoted by decltype(e) is defined as follows:

— if e is an id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
— otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of that the statically chosen function;
— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
— otherwise, decltype(e) is the type of e.

The operand of the decltype specifier is an unevaluated operand (Clause 5).

[ Example:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    const int&& foo();
    int i;
    struct A { double x; };
    const A* a = new A();
    decltype(foo()) x1;      // type is const int&&
    decltype(i) x2;          // type is int
    decltype(a->x) x3;       // type is double
    decltype((a->x)) x4;     // type is const double&
—end example ]

Автор: Большой 25.02.09, 18:52
Цитата archimed7592 @
Большой, ты о чём? Откуда эти выкладки? Ссылку хоть дай.

из рабочего черновика :)

Автор: Большой 26.02.09, 08:54
Masterkent
decltype() - что это вообще?
тип, функция, оператор? наверное врыжение результатом которого является тип.
Чтобы мозг зацепился за понятие этой темы необходимо это знать.

Автор: archimed7592 26.02.09, 10:31
Цитата Большой @
врыжение результатом которого является тип.

Автор: Masterkent 27.02.09, 20:36
decltype(expression) - это спецификатор типа, обозначающий тип :) Какой именно тип он обозначает, определяется правилами в 7.1.6.2/4. Типы не являются выражениями, поэтому decltype(expression) - это не выражение.

Автор: Большой 04.03.09, 08:24
Цитата Masterkent @
decltype((i)) x2; // int &

почему?

Автор: Masterkent 04.03.09, 12:38
Цитата Большой @
почему?

Потому что это подходит под 3-й случай:

Цитата
The type denoted by decltype(e) is defined as follows:

— if e is an id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
— otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of that the statically chosen function;
— otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
— otherwise, decltype(e) is the type of e.

lvalue-ссылка здесь показывает, что выражение является lvalue, а не rvalue. Аналогичное соглашение используется для типа возврата из функции: результатом вызова функции является lvalue, если тип возврата является lvalue-ссылкой, иначе результатом будет rvalue. Таким образом, decltype может быть использован в записи типа возвращаемого значения.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int i;
    enum { e };
     
    // возвращает оригинальный объект i по lvalue-ссылке
    decltype(i) get_i() { return i; }
     
    // возвращает временный объект, равный e;
    // e не является lvalue и не может быть возвращено по lvalue-ссылке
    decltype(e) get_e() { return e; }

Автор: Большой 05.03.09, 06:00
Masterkent
т.е. (i) интерпритируется как вызов функции?

Автор: archimed7592 05.03.09, 06:59
Цитата Большой @
т.е. (i) интерпритируется как вызов функции?

Нет, как lvalue expression, т.е. выражение, которое может стоять слева от оператора присваивания.
Отличие (i) от i в том, что i - это переменная, к примеру, а (i) - это выражение.

Автор: Большой 06.03.09, 12:28
что такое "derived-declarator-type-list" ?
в составе "derived-declarator-type-list T"
или "derived-declarator-type-list reference to T"

В предложении
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    In a declaration T D where D has either of the forms
    & D1
    && D1
    and the type of the identifer in the declaration T D1 is “derived-declarator-type-list T,” then the type of the
    identi?er of D is “derived-declarator-type-list reference to T.”

Автор: Flex Ferrum 01.04.09, 07:01
Так, ну вот. Зарелизили gcc 4.4.0. Из вкусностей C++0x, которые можно попробовать:
- Extending variadic template template parameters
- Initializer lists
- auto-typed variables (!!!)
- Removal of auto as a storage-class specifier
- New function declarator syntax (в рамках auto)
- Solving the SFINAE problem for expressions
- Strongly-typed enums
- Defaulted and deleted functions
- Inline namespaces

В качестве отдельных патчей:
- Delegating constructors
- Lambda expressions and closures
- Concepts

(последние два - в активной разработке).

Любителям TDM-сборок MinGW придется немножко подождать... Сколько - не известно... :(

Автор: Большой 09.04.09, 07:57
Цитата archimed7592 @
T &rt = t; // lvalue reference
T &rrt = t; // rvalue reference


что-то я не вижу разницы между этими двумя объявлениями или упустил что-то из виду?

Автор: Большой 09.04.09, 18:47
Цитата archimed7592 @
void g(long & a1)
{
++a1;
}

template<class A1> void f(A1 && a1)
{
g(static_cast<A1 &&>(a1));
}

int i = 5;
g(i); //fails - int & to long & - запрещённый каст ещё в C++03
f(i); //fails
// A1 выводится(deduced) как int &


непонял
а почему int& а не просто int

Автор: pan2004 13.04.09, 09:38
Цитата Flex Ferrum @
Зарелизили gcc 4.4.0.
...
В качестве отдельных патчей:
- Delegating constructors
- Lambda expressions and closures
- Concepts

Известно когда их с основной веткой объединят? Особенно lambda интересует.

Автор: Большой 13.04.09, 11:08
archimed7592
Проверил под COdegear 2009

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void g(long & a1)
    {
        ++a1;
    }
     
    template<class A1> void f(A1 && a1)
    {
        g(static_cast<A1 &&>(a1));
    }

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    long i = 5;
    g(i);
    f(i); //7
    f<long>(i); //8
    f<long&>(i); //9
    f<long&&>(i); //10

Ответ для всех версий одинаков в переменной i всегда инкрементируемое значение

Автор: archimed7592 13.04.09, 11:20
Цитата Большой @
Ответ для всех версий одинаков в переменной i всегда инкрементируемое значение

Так и должно быть. Это же forwarding. Представь, что ты каждый раз вызываешь g.

Автор: доцент 22.04.09, 17:46
archimed7592
Интересно звучит, а понять как?

Автор: Леголегс 30.04.09, 13:13
Кто разобрался в новом стандарте, поясните. Я правильно пинимаю, что rvalue-ссылки позволяют создавать операторы переноса operator=(T && t) в дополнение к операторам копирования operator=(const T & t) и как только такое будет реализовано для контейнеров стандартной библиотеки код типа нижеприведённого резко ускорится без модификаций?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    vector < vector<char> > vv;
    vv.push_back(vector<char>(100000));

Автор: Flex Ferrum 30.04.09, 13:18
Цитата Леголегс @
Кто разобрался в новом стандарте, поясните. Я правильно пинимаю, что rvalue-ссылки позволяют создавать операторы переноса operator=(T && t) в дополнение к операторам копирования operator=(const T & t) и как только такое будет реализовано для контейнеров стандартной библиотеки код типа нижеприведённого резко ускорится без модификаций?

По-идее, да.

Автор: mas912 01.05.09, 07:45
Цитата Flex Ferrum @
Любителям TDM-сборок MinGW придется немножко подождать... Сколько - не известно..

GCC 4.4.0 для винды, сам гцц, без всего пакета mingw. Но для поиграться или отладить что-то по-быстрому самое то.


Цитата pan2004 @
Известно когда их с основной веткой объединят? Особенно lambda интересует.

Вот это и меня интересует. И вообще, может кто в курсе плана развития гцц? Типа, что будет в след. версии, когда и тюпю.

Вот, кстати, ссылка на состояние поддержки С++0х в различных компиляторах: тыц. Познавательно. Хотя мне непонятно, почему никто до сих пор не поддерживает nullptr.

Автор: Большой 10.05.09, 11:50
Похоже стандарт только в 2011 году появится

Автор: mas912 12.05.09, 20:33
Да, не раньше :wall: Разработчикам стандартной библиотеки есть время накодить и отладить даже по бумажке.

Автор: Radagast 19.05.09, 19:21
какие есть реальные препятствия тому, чтобы Стандарт появился в этом году?

Автор: mas912 21.05.09, 06:26
Без понятия. Но - 3 заседания комитета в год :o
В слайдах BoostCon09 был примерный план принятия.

Автор: Radagast 27.05.09, 21:13
отвечая на собственный вопрос :D
http://www.research.att.com/~bs/C++0xFAQ.html#what-features
Цитата
The standard is expected to be ready for final national votes in 2009 -- hopefully yielding C++09 even if the ISO bureaucracy takes some time work through its formalities.

Учитывая последнюю дату изменения - 15 мая, думаю, эта фраза всё еще актуальна...будем надеяться...

Добавлено
Цитата
After about a year's work -- probably September 2009 -- the committee will vote out a final draft for the national standards bodies to vote on. That final draft (FDIS) is likely to become the new standard with only typographical changes a few months later.

Автор: D_KEY 23.06.09, 06:42
Кто-нибудь подробно уже изучал С++'ные лямбды? Как сделать рекурсивную лямбда-функцию на новом С++?

Автор: Flex Ferrum 23.06.09, 06:44
Цитата D_KEY @
Кто-нибудь подробно уже изучал С++'ные лямбды? Как сделать рекурсивную лямбда-функцию на новом С++?

Видимо, об этом ты нам расскажешь. :)

Автор: D_KEY 23.06.09, 06:54
Цитата Flex Ferrum @
Цитата D_KEY @
Кто-нибудь подробно уже изучал С++'ные лямбды? Как сделать рекурсивную лямбда-функцию на новом С++?

Видимо, об этом ты нам расскажешь. :)

Если узнаю как, расскажу ;)

Автор: mas912 23.06.09, 07:12
D_KEY
Подойдёт?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    []{[](){}();}();

Автор: D_KEY 23.06.09, 07:19
Цитата mas912 @
D_KEY
Подойдёт?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    []{[](){}();}();

А можно объяснить?
Почему после первых [] идет не список аргументов, а тело? Почему после вложенного пустого тела и "главного" тела, идут ()?

Автор: mas912 23.06.09, 10:04
lambda-decl { lambda2-decl { lambda2-call} } lambda-call
где decl - объявление: [] и []()
call - вызов: ();

Список аргументов можно не писать, если он пуст; скобки идут для вызова, то есть, в теле лямбды1 идёт объявление и вызов лямбды2, после чего идёт вызов лямбды1.

Автор: D_KEY 23.06.09, 10:13
Цитата mas912 @
lambda-decl { lambda2-decl { lambda2-call} } lambda-call
где decl - объявление: [] и []()
call - вызов: ();

Список аргументов можно не писать, если он пуст; скобки идут для вызова, то есть, в теле лямбды1 идёт объявление и вызов лямбды2, после чего идёт вызов лямбды1.

Спасибо! Кажется понял...
Хотя, я не понимаю, где тут рекурсия... Как вызвать в теле лямбды эту же лямбда-функцию?
Как будет выглядеть, например, рекурсивное вычисление факториала с помощью лямбда?
Вот обычная функция:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int f( int n )
    {
        return n < 2 ? 1 : n * f(n-1);
    }

Автор: MT-Wizard 23.06.09, 11:11
Цитата D_KEY @
Вот обычная функция: ...

А вот лямбда:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::function<unsigned(unsigned)> f =
       [&f](const unsigned n)
       {
          return n < 2 ? 1 : n * f(n - 1);
       };

Автор: D_KEY 23.06.09, 11:22
Цитата MT-Wizard @
Цитата D_KEY @
Вот обычная функция: ...

А вот лямбда:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::function<unsigned(unsigned)> f =
       [&f](const unsigned n)
       {
          return n < 2 ? 1 : n * f(n - 1);
       };

Такой вариант приходит в голову, но не нет ли здесь неопределенного поведения, ведь f - неинициализированный объект на момент передачи в лямбда-функцию?

Автор: MT-Wizard 23.06.09, 12:06
Цитата D_KEY @
но нет ли здесь неопределенного поведения

А в чём принципиальное отличие от
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::function<unsigned(unsigned)> f;
    f = [&f](const unsigned n)
       {
          return n < 2 ? 1 : n * f(n - 1);
       };
?
Ведь внутри будет использовано значение f на момент вызова лямбды.

Автор: D_KEY 23.06.09, 12:09
Цитата MT-Wizard @
Цитата D_KEY @
но нет ли здесь неопределенного поведения

А в чём принципиальное отличие от
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::function<unsigned(unsigned)> f;
    f = [&f](const unsigned n)
       {
          return n < 2 ? 1 : n * f(n - 1);
       };
?
Ведь внутри будет использовано значение f на момент вызова лямбды.

Скорее всего, действительно верно. Спасибо! Жаль, что нельзя сделать рекурсию без введения дополнительных сущностей...

Автор: MT-Wizard 23.06.09, 12:29
Цитата D_KEY @
Жаль, что нельзя сделать рекурсию без введения дополнительных сущностей...

Не придумали аналога this для лямбды :)

Автор: mas912 23.06.09, 13:41
D_KEY
Инициализированный. Присваивание лямбды в функцию будет в рантайме, вызов тоже (и вызов функции из лямбды).

Автор: Большой 24.06.09, 12:53
Цитата Flex Ferrum @
Любителям TDM-сборок MinGW придется немножко подождать... Сколько - не известно...


ура появились

Автор: Flex Ferrum 24.06.09, 12:55
Цитата Большой @
ура появились

Ага. Достаточно давно уже. Я тут еще из их репозитория выкачал бранч с поддержкой лямбд - тоже весьма зачетно. Хотя при сборке (под виндой) без бубна не обошлось. :)

Автор: pan2004 24.06.09, 17:58
Цитата Flex Ferrum @
Я тут еще из их репозитория выкачал бранч с поддержкой лямбд - тоже весьма зачетно

И насколько они там развиты? К gcc 4.5 включить их в основную ветку могут?

Автор: Flex Ferrum 24.06.09, 18:22
Цитата pan2004 @
И насколько они там развиты?

Ну, простые случаи работает. А вглубь не копал.

Автор: Flex Ferrum 19.07.09, 17:29
Итак, на последней встрече во Франкфурте комитет проголосовал за то, чтобы Concepts были исключены из текущего драфта стандарта:
Цитата
On Monday, July 13th 2009 Concepts were dramatically voted out of C++0x during the C++ standards committee meeting in Frankfurt. This shocking news raises many questions and concerns. Unquestionably, these will be discussed in various forums in coming weeks and months. However, I will try to answer three burning questions here: What led to the failure of Concepts? How will the removal of Concepts affect C++0x? Will Concepts make a comeback in the near future?

http://www.informit.com/guides/content.asp...plus&seqNum=441

Комментарий из списка рассылки comp.std.c++:
Цитата
The Committee voted to remove concepts from the version of the standard
now being worked on because we estimated it would take at least 2 more
years, and possibly 5, to complete the work and publish.

With many other desirable features ready to go, and with the current
standard already more than 10 years old, that seemed too long a delay.

The choice was difficult, and nobody was happy about having to drop
concepts, but the alternatives -- 5 years delay or standardizing an
unusable version of concepts -- were far worse.

Removing concepts will take some time, so the publication date of the
new standard might slip by 3 months or so, due specifically to the
removal of concepts. As Beman noted in an earlier message, we had to
lengthen our schedule still more for other reasons.

The Committee still wants concepts in C++, and will continue developing
it in anticipation of the next update of the standard.

The Removal of Concepts From C++0x

Так что в принципе, не все так плохо.

Если кто-то кинет ссылку на полный review их франкфуртской встречи - будет просто супер!

Автор: miksayer 19.07.09, 20:35
Цитата Flex Ferrum @
Concepts

а что это такое? киньте, пожалуйста, ссылку, где можно почитать

Автор: DEADHUNT 19.07.09, 20:51
Цитата miksayer @
а что это такое? киньте, пожалуйста, ссылку, где можно почитать

www.open-std.org

Автор: DEADHUNT 22.07.09, 13:07
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class T {
        public:
            void foo() const &&
            {
            }
    };

в данном методе this будет иметь тип const T &&this? а то в 9.3.2 ничего не написано про ref-qualifier.

Автор: Masterkent 22.07.09, 16:23
Цитата DEADHUNT @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class T {
        public:
            void foo() const &&
            {
            }
    };

в данном методе this будет иметь тип const T &&this?

В данном методе выражение this (если его туда поместить) - это rvalue типа T const *.

Цитата DEADHUNT @
а то в 9.3.2 ничего не написано про ref-qualifier.

Раз не написано, значит, на тип this он никак не влияет.

Автор: DEADHUNT 22.07.09, 16:57
Цитата Masterkent @
Раз не написано, значит, на тип this он никак не влияет.

как это не влиет, если ref-qualifier предназначен для non-static class member.

Автор: Masterkent 22.07.09, 19:19
Цитата DEADHUNT @
как это не влиет, если ref-qualifier предназначен для non-static class member.

А зачем ему влиять на тип this? :huh: Он предназначен для различения lvalue и rvalue, передаваемых в качестве implied object argument, - по аналогии с обычными аргументами функции:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct X
    {
        static void f(X const &);
        static void f(X &&);
        void g() const &; // type of implicit object parameter is X const &
        void g() &&;      // type of implicit object parameter is X &&
    };
     
    void h()
    {
        X x;
        X::f(x);   // calls f(X const &)
        X::f(X()); // calls f(X &&)
        x.g();     // calls g() const &
        X().g();   // calls g() &&
    }

this тут не при делах вообще.

Автор: DEADHUNT 22.07.09, 19:44
Цитата Masterkent @
this тут не при делах вообще.

спасибо за примеры, буду разбираться.

Автор: Hryak 24.07.09, 19:08
А, вот ты про что...
Дык, что касается ругательств только GCC - сам же привёл про "no diagnostic is required", чего ты от компиляторов хочешь...
А к (1) приведенные тобой цитаты не подошьёшь, т.к. имя i в аргументе по умолчанию однозначно ссылается на член класса (см выше про "an unqualified name that occurs, for instance, in a type or default argument expression in the parameter-declaration-clause")

Автор: DEADHUNT 24.07.09, 19:26
Цитата Hryak @
А к (1) приведенные тобой цитаты не подошьёшь

как же нет, при первом просмотре ссылка идёт на ::i, а имея complete scope уже на X::i, и как раз получается 2) пункт.
Цитата Hryak @
сам же привёл про "no diagnostic is required", чего ты от компиляторов хочешь...

то есть error это слишком строго, лучше warning а какого уровня(1-4)?

Автор: Hryak 24.07.09, 19:32
Цитата DEADHUNT @
при первом просмотре ссылка идёт на ::i, а имея complete scope уже на X::i, и как раз получается 2) пункт.

Нет там никаких первых и вторых просмотров для аргумента по умолчанию, просто "shall be a member of class X or be a member of a base class of X". Это для использования в определении класса "before its use in class X".

Цитата DEADHUNT @
то есть error это слишком строго

Да не слишком строго, "the program"-то "is ill-formed"...

Автор: Большой 31.07.09, 09:11
Доступен GCC 4.4.1

Похоже лямбд и в GCC 4.5 небудет :(

Автор: Flex Ferrum 31.07.09, 09:13
Цитата Большой @
Похоже лямбд и в GCC 4.5 небудет :(

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

Автор: DEADHUNT 31.07.09, 09:32
Цитата Flex Ferrum @
Скачай себе бранч, и пользуйся. :) Только его сначала сбилдить надо. По поводу мерджа в лямбд в транк - я так понял, что человек, который решил реализовать лямбды в gcc, забил на это в конце прошлого года (судя по истории изменений). Подхватит ли кто его флаг? Вот вопрос. :)

всеволишь объект создать с оператором (), как я понял вроде ничего сложного.

Автор: Flex Ferrum 31.07.09, 09:39
Цитата DEADHUNT @
всеволишь объект создать с оператором (), как я понял вроде ничего сложного.

Я так понял, что есть там свои тонкости. Глубоко не вникал, но с capture-списком нужно повозиться.

Автор: Большой 31.07.09, 15:32
Цитата DEADHUNT @
всеволишь объект создать с оператором (), как я понял вроде ничего сложного.

непонял ты к чему.

Добавлено
Flex Ferrum Скачай себе бранч, и пользуйся
что это и где взять?

Автор: DEADHUNT 31.07.09, 15:48
Цитата Большой @
Flex Ferrum Скачай себе бранч, и пользуйся
что это и где взять?

если не знаешь что это такое, то тебе лучше не брать :P
но на всякий случай http://gcc.gnu.org/svn/gcc/branches/cxx0x-lambdas-branch/

Автор: Большой 31.07.09, 16:30
Цитата DEADHUNT @
если не знаешь что это такое, то тебе лучше не брать

Очень хорошая шутка

Добавлено
Flex Ferrum
я так и не понял,они чё совсем лямбды делать не будут?

Автор: DEADHUNT 31.07.09, 16:46
Цитата Большой @
я так и не понял,они чё совсем лямбды делать не будут?

http://gcc.gnu.org/gcc-4.5/cxx0x_status.html
пока наверное нет, а зачем так понадобились lambda-expressions?

Автор: Большой 31.07.09, 16:49
DEADHUNT
Надоело функторы писать состоящие из 2-3 строк кода.

Автор: Flex Ferrum 31.07.09, 17:25
Цитата Большой @
я так и не понял,они чё совсем лямбды делать не будут?

А я почем знаю? Я за их мейл-листом не слежу. :)


Цитата Большой @
что это и где взять?

Качаешь исходники из их репозитория (ветку с лямбдами), выкчиваешь еще пару библиотек (для работы с длинными целыми и еще какую-то), компилируешь с помощью текущей версии gcc (компиляет достаточно быстро), делаешь make install, и пользуешься. А, да. К MinGW нужно msys выкачать (без него не сделаешь autoconf/automake).

Автор: Flex Ferrum 02.08.09, 17:47
Цитата Flex Ferrum @
Качаешь исходники из их репозитория (ветку с лямбдами), выкчиваешь еще пару библиотек (для работы с длинными целыми и еще какую-то), компилируешь с помощью текущей версии gcc (компиляет достаточно быстро), делаешь make install, и пользуешься. А, да. К MinGW нужно msys выкачать (без него не сделаешь autoconf/automake).

Не, на самом деле - это я погорячился. gcc 4.5 (основной транк) собрать под винду - это тот еще квест. :) Но, вполне проходимый... :D

Автор: Большой 02.08.09, 20:30
Flex Ferrum
да, засада.
Подожду еще. (Пока еще не сильно приперло)

Автор: Flex Ferrum 03.08.09, 07:59
Цитата Большой @
да, засада.

Ну, на самом деле там не все так страшно. Просто долго времени ушло на выяснение правильной последовательности запуска make'ов. Засада в другом. Бранч (который с лямбдами) содержит как минимум одну достадную ошибку в плане обработки блока __try/__catch. Выяснил это позавчера, когда игрался с std::unordered_map. Основной транк этой ошибки не содержит, но с лямбдами его мерджить надо.

Автор: DEADHUNT 03.08.09, 08:03
Цитата Flex Ferrum @
ошибку в плане обработки блока __try/__catch

зачем в gcc __try/__catch? :wacko:

Автор: Flex Ferrum 03.08.09, 08:09
Цитата DEADHUNT @
зачем в gcc __try/__catch? :wacko:

А я почем знаю? :wacko:

Добавлено
Код, который вызывал ошибку:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      // Definitions of class template _Hashtable's out-of-line member functions.
      template<typename _Key, typename _Value,
           typename _Allocator, typename _ExtractKey, typename _Equal,
           typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
           bool __chc, bool __cit, bool __uk>
        typename _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
                _H1, _H2, _Hash, _RehashPolicy,
                __chc, __cit, __uk>::_Node*
        _Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal,
               _H1, _H2, _Hash, _RehashPolicy, __chc, __cit, __uk>::
        _M_allocate_node(const value_type& __v)
        {
          _Node* __n = _M_node_allocator.allocate(1);
         __try
        {
    #ifdef _GLIBCXX_INCLUDE_AS_CXX0X
          _M_node_allocator.construct(__n, __v);
    #else
          _M_get_Value_allocator().construct(&__n->_M_v, __v);
    #endif
          __n->_M_next = 0;
        }
          __catch(...)
        {
          _M_node_allocator.deallocate(__n, 1);
          __throw_exception_again;
        }
          return __n;
        }

Автор: DEADHUNT 03.08.09, 08:12
Цитата Flex Ferrum @
Код, который вызывал ошибку:

теперь понятно, они просто там ещё и C++ используют.

Автор: archimed7592 03.08.09, 08:17
Цитата DEADHUNT @
там ещё и C++ используют

Нда... :rolleyes:

Автор: Flex Ferrum 03.08.09, 08:26
Цитата DEADHUNT @
теперь понятно, они просто там ещё и C++ используют.

Да не, ты не понял. Это исходники STL (часть реализации unordered_map). Сам gcc - на чистом C. C++-реализация - в отдельном бранче болтается. :)

Автор: DEADHUNT 03.08.09, 08:30
в STL конечно надо использовать обработку исключений.

Автор: Flex Ferrum 03.08.09, 19:06
Цитата archimed7592 @
Нда... :rolleyes:

Кстати, шутки - шутками, а часть фронт-энда на плюсах уже переписали. Уже зашли разговоры о том, чтобы основной транк 4.5 переводить на плюсовую реализацию...
Также есть немалая вероятность, что лямбды в 4.5 таки будут.

Автор: DEADHUNT 03.08.09, 19:51
Цитата Flex Ferrum @
Также есть немалая вероятность, что лямбды в 4.5 таки будут.

откуда такая вероятность?
Цитата Flex Ferrum @
По поводу мерджа в лямбд в транк - я так понял, что человек, который решил реализовать лямбды в gcc, забил на это в конце прошлого года (судя по истории изменений).

Автор: miksayer 03.08.09, 21:00
Цитата Flex Ferrum @
Также есть немалая вероятность, что лямбды в 4.5 таки будут.

кстати, а что у msvc предвидится по этому вопросу?

Автор: Flex Ferrum 04.08.09, 06:38
Цитата DEADHUNT @
откуда такая вероятность?

http://gcc.gnu.org/ml/gcc/2009-08/msg00038.html

Добавлено
Кстати, занятные идеи по поводу лямбд здесь описываются:

http://gcc.gnu.org/ml/gcc/2009-08/msg00045.html
Причем, судя по всему, версия в бранче их кушает... :huh:

Добавлено
Сам некоторое количество раз порывался написать auto в качестве аргумента лямбда-функции. Но, компиль не скушал... :)

Добавлено
Да, и ветку с лямбдами таки смёрджили. Пойду перекомпилять. :)

Автор: Большой 19.08.09, 21:50
Цитата Flex Ferrum @
Также есть немалая вероятность, что лямбды в 4.5 таки будут.

было бы совсем хорошо.

Автор: mas912 21.08.09, 20:21
miksayer
В смысле, предвидится? В MSVC уже есть, начиная с CTP они (лямбды). В ICC тоже.

Flex Ferrum
Просто в транке она или есть в каком-нить snapshot'e? Просто из транка боюсь собирать :rolleyes:, неохота сырой компилятор ставить в системе.

Добавлено
Цитата
Также есть немалая вероятность, что лямбды в 4.5 таки будут.

А, лучше бы nullptr прикрутили, вкупе с constexpr (последнего жутко не хватает и никто до сих пор не сделал).

Автор: Flex Ferrum 21.08.09, 21:47
Цитата mas912 @
Просто в транке она или есть в каком-нить snapshot'e?

Нет. Только в бранче. Снапшот (собранный) есть у меня. Попробую с Vot'ом договориться, и свой билд здесь выложить (архив, правда, в райное двухсот метров, exe-шники не strip'пил).

Цитата mas912 @
А, лучше бы nullptr прикрутили, вкупе с constexpr (последнего жутко не хватает и никто до сих пор не сделал).

А мне, например, raw-строковых литералов.

Автор: mas912 22.08.09, 08:39
А почему в бранче? Я думал, разработку ведут в транке, "тэгя" релизы и "бранча" экспериментальные ветки + поддерживаемые релизы.

По поводу raw строк, где-то видел патч, там тривиально, и странно, что его до сих пор не включили в транк.

Автор: Flex Ferrum 28.08.09, 17:15
Выложил свою сборку gcc 4.5 (mingw) с лямбдами.

Информация о версии:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    P:\Temp\gcc\MinGW\libexec\gcc\mingw32\4.5.0>gcc -v
    Using built-in specs.
    Target: mingw32
    Configured with: ../../configure --prefix=/mingw --host=mingw32 --target=mingw32 --program-prefix= --with-as=/mingw/bin/
    as.exe --with-ld=/mingw/bin/ld.exe --with-gcc --with-gnu-ld --with-gnu-as --enable-threads --disable-nls --enable-langua
    ges=c,c++ --disable-win32-registry --disable-shared --without-x --enable-interpreter --enable-hash-synchronization --ena
    ble-libstdcxx-debug --with-gmp-include=/projects/common/GMP/4.3.1 --with-gmp-lib=/projects/common/GMP/4.3.1/.libs --with
    -mpfr-include=/projects/common/MPFR/2.4.1 --with-mpfr-lib=/projects/common/MPFR/2.4.1/.libs : (reconfigured) ../../confi
    gure --prefix=/mingw --host=mingw32 --target=mingw32 --program-prefix= --with-as=/mingw/bin/as.exe --with-ld=/mingw/bin/
    ld.exe --with-gcc --with-gnu-ld --with-gnu-as --enable-threads --disable-nls --disable-win32-registry --disable-shared -
    -without-x --enable-interpreter --enable-hash-synchronization --enable-libstdcxx-debug --with-gmp-include=/projects/comm
    on/GMP/4.3.1 --with-gmp-lib=/projects/common/GMP/4.3.1/.libs --with-mpfr-include=/projects/common/MPFR/2.4.1 --with-mpfr
    -lib=/projects/common/MPFR/2.4.1/.libs host_alias=mingw32 target_alias=mingw32 --enable-languages=c,c++ --no-create --no
    -recursion
    Thread model: win32
    gcc version 4.5.0 20090803 (experimental) (GCC)


Добавлено
Выложил cвой стапшот as-is... За работоспособность не ручаюсь, но у меня работает. :)

Автор: amdei 30.08.09, 03:26
А что такое "raw-строковые литералоы"?

Автор: MyNameIsIgor 30.08.09, 05:07
amdei, смотри первый пост этой темы.

Автор: Бобёр 02.09.09, 07:57
похоже, многие из фич Стандарта 0x будут мочить. уже начали:
http://www.devx.com/cplus/Article/42448/0/
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=441
Стандарт и так уже стал не 0x, а скорее 1x, видимо что бы не стал таки 2x, решили подсократить...

Автор: Flex Ferrum 02.09.09, 08:49
Цитата Бобёр @
похоже, многие из фич Стандарта 0x будут мочить

Бобер, это даже не вчерашняя, это позавчерашняя новость. Пока все идет к тому, что кроме концептов из стандарта ничего выкидывать не будут.

Автор: Бобёр 02.09.09, 08:58
ну, посмотрим.

Автор: Qraizer 02.09.09, 10:37
А концепты жалко. Я так на них рассчитывал...

Автор: Flex Ferrum 02.09.09, 10:44
Цитата Qraizer @
А концепты жалко. Я так на них рассчитывал...

Ну, видимо, не один ты. :) Попробуй собрать ветку концептов из репозитория gcc. Я так понял, что ее ведут как раз те же люди, которые продвигают концепты в стандарте.

Автор: Qraizer 02.09.09, 11:02
А смысл, если это всего лишь расширение Стандарта получится? Руку набить разве что. Я хочу ими "документировать" и хочу избавиться от расшифровки диагностик (мой личный рекорд: одна ошибка - 1,3Мб листинг). Вон, typeof там сроду был, полезнейшая вещь иногда. И часто его можно было видеть, когда он был нужен?

Автор: Flex Ferrum 02.09.09, 11:03
Цитата Qraizer @
А смысл, если это всего-лишь рассширение Стандарта?


Цитата Qraizer @
Я так на них рассчитывал...

;)

Автор: mas912 03.09.09, 10:33
Интересно, концепты пойдут в TR2 или TR3.

Автор: Flex Ferrum 03.09.09, 10:37
Цитата mas912 @
Интересно, концепты пойдут в TR2 или TR3.

Вопрос хороший. И вопрос еще лучше - а где посмотреть текущее состояние TR2? Гугл практически никаких ссылок не дает... :wall:

Автор: mas912 03.09.09, 12:41
Самое последнее, что я видел, это C++ Library Working Group Status Report (Post San Francisco 2008) (N2870, там есть разделы "New Library Components Accepted into TR2", "New Library Components Planned for a Future TR", "Evolution of papers targetting future TRs".

Большинство предложений там из буста (filesystem, networking (boost.asio), ranges, etc.). Но это по библиотекам, а вот что по самому языку, мне неизвестно.

Автор: Flex Ferrum 25.09.09, 05:36
Yes!
Цитата

Re: C++0x lambdas in 4.5?

* From: Jason Merrill <jason at redhat dot com>
* To: Kenny Simpson <theonetruekenny at yahoo dot com>
* Cc: gcc at gcc dot gnu dot org
* Date: Thu, 24 Sep 2009 10:44:38 -0400
* Subject: Re: C++0x lambdas in 4.5?
* References: <603843.64256.qm@web51508.mail.re2.yahoo.com>

On 09/22/2009 10:16 PM, Kenny Simpson wrote:

Will the lambda branch be merged into 4.5?


Yes.

Jason

http://gcc.gnu.org/ml/gcc/2009-09/msg00507.html

Автор: Masterkent 25.09.09, 19:51
Поскольку в последнее время на форуме стали много поговаривать о хаках вокруг std::basic_string, не лишним будет заметить, что в стандарте планируются важные изменения насчёт строк:

1) непрерывность расположения элементов std::basic_string будет гарантироваться, как и в случае с std::vector:

Цитата N2914 - 21.4.1/3
The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size().

Цитата 21.4.5
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);

1 Returns: If pos < size(), returns *(begin() + pos). Otherwise, if pos == size(), the const version returns charT(). Otherwise, the behavior is undefined.

2) Copy-on-write реализации std::basic_string не будут допускаться. Как альтернатива std::basic_string, возможно, появится rope (или что-то похожее) с применением этой идиомы.

Подробности см. в N2668

Цитата 21.4.1/4
References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated
by the following uses of that basic_string object:
— as an argument to any standard library function taking a reference to non-const basic_string as an argument.234
— Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and rend.

Если это дело примут, то хак вроде

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <cstddef>
    #include <iostream>
    #include <string>
     
    int main()
    {
        std::size_t const size = 5;
        std::string s(size, '\0');
        std::cin.read(&s[0], size);  // undefined behavior in C++03, well-defined in C++0x
        std::cout << s << std::endl;
    }

перестанет быть хаком.

Автор: archimed7592 25.09.09, 19:58
Цитата Masterkent @
2) Copy-on-write реализации std::basic_string не будут допускаться

Хммм... А из каких именно соображений, случаем, не знаешь?

Автор: Masterkent 25.09.09, 20:00
Цитата archimed7592 @
Хммм... А из каких именно соображений, случаем, не знаешь?

В основном это связано с конкурентным доступом. По ссылке всё объяснено.

Правда, я пока так и не понял смысл предлагаемого определения c_str и data.

Автор: Masterkent 26.09.09, 15:21
Цитата Masterkent @
Правда, я пока так и не понял смысл предлагаемого определения c_str и data.

Мда, похоже, не мне одному описание c_str и data в N2914 представляется неподходящим - см. issue 876. Вот это

Цитата
In 21.4.7.1 [string.accessors] replace the now common returns clause of c_str() and data() by the following three paragraphs:

Returns: A pointer p such that p+i == &operator[](i) for each i in [0, size()].

Throws: Nothing.

Complexity: Constant time.

уже как-то получше будет :whistle:

Автор: Flex Ferrum 06.10.09, 18:06
Да. lambda branch действительно смерджили с основным транком gcc. Помимо лямбд там появятся:
- Explicit conversion operators
- Standard Layout Types
- Local and unnamed types as template arguments

Добавлено
Последняя фишка весьма забавная, надо отметить.

Автор: Большой 08.10.09, 05:24
Цитата archimed7592 @
T t; // lvalue
T &rt = t; // lvalue reference
T &&rrt = t; // rvalue reference


Я что-то не пойму ссылка на ссылку объявляется так как в примере выше?

Я просто думал, что так

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    T t;
    T &rt = t;
    T &&rrt = rt;

Автор: Flex Ferrum 08.10.09, 05:46
Цитата Большой @
Я что-то не пойму ссылка на ссылку объявляется так как в примере выше?

Да.

Добавлено
Вопрос к Masterkent'у.
Masterkent, не известно ли тебе - по какой причине в новой версии стандарта всё еще запрещено объявлять шаблонные члены в локальных классах? Просто забавно получается - в качестве шаблонных параметров их разрешили использовать, а шаблонизировать сами эти классы - нет. Иначе как было бы здорово (на мой взгляд) объявлять полиморфные функторы:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // Некий обобщенный код:
    template<typename T1, typename T2, typename F>
    void generic_foo(T1 a, T2 b, F fn)
    {
       // ...
       fn(a, b);
       // ...
    }
     
    void foo(int a, double b) {}
    void foo(std::string a, char b) {}
     
    void bar()
    {
       class FTor
       {
          template<typename T1, typename T2>
          void operator()(T1 a, T2 b) {foo(a, b);}
       } ftor;
     
       generic_foo(10, 103.2, ftor);
       generic_foo(std::string("abeagew"), 'a', ftor);
    }


Но... Так нельзя... :(

Автор: archimed7592 08.10.09, 09:10
Цитата Большой @
Я что-то не пойму ссылка на ссылку объявляется так как в примере выше?

Это не ссылка на ссылку. Это rvalue ссылка (в отличии от lvalue ссылки). Разница между ними настолько же существенная, как и между указателем и ссылкой.

Автор: Большой 08.10.09, 11:15
archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue?
или опять я туплю

Автор: Flex Ferrum 08.10.09, 11:18
Цитата Большой @
archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue?

Да.

Автор: archimed7592 08.10.09, 12:25
Цитата Большой @
archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue?
или опять я туплю

1. Это не ссылка на ссылку.
2. Это называется rvalue reference, а как правильнее обзывать - решай сам.
3. Базовую информацию о том, что такое rvalue reference и чем она отличается от lvalue reference ты можешь получить в первом посте.
4. Зная что представляет из себя ссылка по определениям C++03 (а это определение сильно не изменилось в С++09), ты бы понимал, что ссылка на ссылку - это некая абстрактная сущность (которой к слову в С++09 не появилось), которая не имеет абсолютно никакого смысла.

Объясню про п. 4 чуть подробнее. Есть такое понятие как указатель на указатель на T. Смысл этой сущности состоит в том, что с её помощью можно изменять значение некоторого объекта ссылающегося на объект типа T, т.е. модифицировать указатель.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x, y;
    int *pi = &x, **ppi = π
    x = 10;
    y = 20;
    std::cout << *pi << std::endl; // 10;
    x += 5;
    std::cout << *pi << std::endl; // 15;
    *ppi = &y;
    std::cout << *pi << std::endl; // 20;
    y += 5;
    std::cout << *pi << std::endl; // 25;


Что же касается ссылки - связь с объектом на который она указывает ссылка получает во время инициализации и изменить эту связь таким образом, чтобы ссылка ссылалась на другой объект в принципе невозможно (формально, да, можно подменить объект в памяти другим при помощи new (ptr) T(), но изменением связи это назвать сложно). Тот факт что технически ссылка может представлять из себя объект, указывающий на другой объект, т.е. указатель никаким образом не помогает нам изменить связь ссылки с объектом, если так будет проще: в С++ не предусмотрено для этих целей синтаксиса; ни в С++03, ни в С++09. Для более лёгко понимания того, что из себя представляет ссылка в некоторой литературе советуют воспринимать ссылку как синоним имени объекта для доступа к нему. Как ты сам понимаешь синоним на синоним всё равно будет представлять из себя синоним.

Автор: Masterkent 08.10.09, 14:35
Цитата Flex Ferrum @
Masterkent, не известно ли тебе - по какой причине в новой версии стандарта всё еще запрещено объявлять шаблонные члены в локальных классах?

Не знаю. IMHO, скорее всего, такое в принципе возможно формализовать (без получения негативных побочных эффектов), но комитет просто не видит в этом достаточной выгоды, чтобы переписывать правила.

Автор: pan2004 08.10.09, 15:36
Цитата Flex Ferrum @
Да. lambda branch действительно смерджили с основным транком gcc. Помимо лямбд там появятся:
- Explicit conversion operators
- Standard Layout Types
- Local and unnamed types as template arguments

Насчет последнего - local понятно, но unnamed это как? Чтото вроде этого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T> class A
    {...};
    void foo()
    {
        A<struct {int a; int b;}> obj;
    }

?

ПС Еще обещают в gcc 4.5 повысить скорость компиляции шаблоного кода и добавить Link-time оптимизацию. Так глядишь и студийный компилятор по скорости догонит...

Автор: Flex Ferrum 08.10.09, 16:52
Цитата pan2004 @
ПС Еще обещают в gcc 4.5 повысить скорость компиляции шаблоного кода и добавить Link-time оптимизацию.

Уже. :)

Автор: Masterkent 08.10.09, 18:11
Цитата pan2004 @
но unnamed это как?

Класс или перечисление получается безымянным, когда в его определении непосредственно после ключевого слова class, struct, union или enum отсутствует имя.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct NamedClass {};
    enum NamedEnumeration { enumerator_of_named_enumeration_type };
     
    typedef struct : NamedClass {} UnnamedClass;     // has name for linkage purposes only
    enum { enumerator_of_unnamed_enumeration_type };
     
    template <class T>
        void f(T) {}
     
    int main()
    {
        f(NamedClass());                            // well-formed in C++03 and C++0x
        f(enumerator_of_named_enumeration_type);    // well-formed in C++03 and C++0x
     
        f(UnnamedClass());                          // ill-formed in C++03, well-formed in C++0x
        f(enumerator_of_unnamed_enumeration_type);  // ill-formed in C++03, well-formed in C++0x
    }

Цитата pan2004 @
Чтото вроде этого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T> class A
    {...};
    void foo()
    {
        A<struct {int a; int b;}> obj;
    }

?

Так делать нельзя:

Цитата N2914 - 14.3/1
template-argument:
    constant-expression
    type-id
    id-expression

Цитата N2914 - 8.1/1
type-id:
    type-specifier-seq attribute-specifieropt abstract-declaratoropt

Цитата N2914 - 7.1.6/3
A type-specifier-seq shall not define a class or enumeration unless it appears in the type-id of an alias-declaration

Автор: Flex Ferrum 08.10.09, 18:15
Цитата Masterkent @
Класс или перечисление получается безымянным, когда в его определении непосредственно после ключевого слова class, struct, union или enum отсутствует имя.

Можешь привести пример (пусть и синтетический) но более-менее реального применения этой фишки?

Автор: Masterkent 08.10.09, 18:20
Цитата Flex Ferrum @
Можешь привести пример (пусть и синтетический) но более-менее реального применения этой фишки?

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

Автор: Flex Ferrum 08.10.09, 18:22
Цитата Masterkent @
Перечислениям очень часто не дают имени, ну а безымянные классы лично мне не пригождались.

Ну, вообще говоря, по-моему, отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов... У них ведь, вроде как (у констант, в смысле) получается тип int. Или я чего-то недопонимаю?

Автор: Masterkent 08.10.09, 18:36
Цитата Flex Ferrum @
отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов

VC++ позволяет инстанцировать шаблоны безымянными типами.

Цитата Flex Ferrum @
У них ведь, вроде как (у констант, в смысле) получается тип int.

Цитата C++03 - 7.2/4
Each enumeration defines a type that is different from all other types. Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration.

Автор: Flex Ferrum 08.10.09, 18:56
Цитата Masterkent @
но комитет просто не видит в этом достаточной выгоды, чтобы переписывать правила.

Странно (на мой взгляд). Достаточно взглянуть на приведенный пример. Ведь это просто следующий шаг (после лямбд и инстанцирования локальными типами). in-place-полиморфные врапперы, избавляющие кодера от, гм..., ненужных шаманств. Другой пример (по идее, должен компилироваться):

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Foo
    {
    public:
       typedef boost::variant<int, std::string, double> var_type;
     
       void Process(var_type const& v)
       {
          struct Processor : boost::static_visitor<>
          {
             Foo* m_Object;
             Processor(Foo* obj) : m_Object(obj) {;}
             template<typename T> void operator()(T val) const {m_Object->Process(val);}
          } p(this);
          
          boost::apply_visitor(p, v);
       }
    private:
     
       void Process(int a);
       void Process(std::string a);
       void Process(double a);
    };

Теперь прикинь, сколько тебе придется писать сейчас. А учитывая, что этот Processor можно завернуть в макрос:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #define DEF_VISITOR(cls, method) \
          struct Processor : boost::static_visitor<> \
          {   \
             cls* m_Object;   \
             Processor(cls* obj) : m_Object(obj) {;}  \
             template<typename T> void operator()(T val) const {m_Object->Method(val);} \
          }

с последующим использованием:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class Foo
    {
    public:
       typedef boost::variant<int, std::string, double> var_type;
     
       void Process(var_type const& v)
       {
          DEF_VISTOR(Foo, Process) p(this);
          
          boost::apply_visitor(p, v);
       }
    private:
     
       void Process(int a);
       void Process(std::string a);
       void Process(double a);
    };

разница становится еще более очевидной.

Добавлено
Только что проверил (на полусобранном gcc 4.5) - локальный класс в теле метода класса имет полный доступ к private-потрохам класса. Что и требуется.

Автор: Qraizer 08.10.09, 19:56
Цитата Flex Ferrum @
Ну, вообще говоря, по-моему, отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов... У них ведь, вроде как (у констант, в смысле) получается тип int. Или я чего-то недопонимаю?
Ну, значениями тебе никто не запрещал пользоваться, перечисления-то не требуют квалификации именем своего типа, т.к. они не создают областей видимости. Но ведь речь-то шла не о значениях, а о типе. Значение параметром в typename T не передашь.
Проблема стала актуальной с появлением decltype и наделением auto новых возможностей. Их-то не запрещается использовать с безымянными типами.

Автор: Большой 09.10.09, 06:29
Flex Ferrum
когда gcc 4.5 обещают?

Автор: Flex Ferrum 09.10.09, 06:34
Цитата Большой @
когда gcc 4.5 обещают?

Я ожидаю не раньше марта следующего года (судя по датам выходов предыдущих релизов). Сейчас четвертый день пытаюсь его из исходников под MinGW сбилдить... :wall: :wall: :wall: Вообщем, как только получится - выложу здесь. :)

Автор: Большой 09.10.09, 09:06
Цитата Flex Ferrum @
Вообщем, как только получится - выложу здесь

было бы очень хорошо

Автор: Masterkent 09.10.09, 10:42
Цитата Flex Ferrum @
Теперь прикинь, сколько тебе придется писать сейчас.

Можно сделать Processor закрытым членом Foo.

Цитата Flex Ferrum @
А учитывая, что этот Processor можно завернуть в макрос

Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение. Указатели на функции-члены неудобны: ни с перегруженными функциями, ни с шаблонами функций, ни с функциями, имеющими аргументы по умолчанию, их зачастую нормально не поюзаешь. Иметь дело с именами функций было бы куда удобнее:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // подобное использование virtual, .(Fn) и .. - это просто мои допущения, в C++0x ничего такого нет.
     
    template <virtual Fn, class C>
        class MemFnBinder
    {
    public:
        MemFnBinder(C const &x) :
            m_obj(x) {}
        template <class... Args>
            auto operator ()(Args &&... args) const -> decltype(m_obj.(Fn)(args...))
                { return m_obj.(Fn)(args...); }
    private:
        C m_obj;
    };
        
    template <virtual Fn, class C>
        MemFnBinder<Fn, C> bind(C const &x)
            { return MemFnBinder<Fn, C>(x); }
        
    struct X
    {
        void func(int, int = 0);
    };
     
    void f()
    {
        std::function<void (int)> fn1       = bind<..func>(X());
        std::function<void (int, int)> fn2  = bind<..func>(X());
    }

И, в частности, твой макрос можно было бы переписать примерно так:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class C, virtual Fn>
        class Processor : boost::static_visitor<>
    {
    public:
        Processor(C* obj) : m_object(obj) {}
        template <class T>
            void operator()(T val) const
                { m_object->(Fn)(val); }
    private:
        C* m_object;
    }

причём, по-моему, не было бы никакого смысла делать такой шаблон локальным. Если он настолько обобщённый, что используется сразу в нескольких местах, то, наверное, ему самое место в пространстве имён. Локальным имело бы смысл делать код, который нигде больше, кроме как в данной функции, не используется - например:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class BidirectionalIterator>
        void reverse(BidirectionalIterator first, BidirectionalIterator last)
    {
        struct Aux
        {
            template <class BidirIt>
                void operator()(BidirIt first, BidirIt last, std::bidirectional_iterator_tag)
            {
                for (; first != last && first != --last; ++first)
                    (swap)(*first, *last);
            }
     
            template <class RanIt>
                void operator ()(RanIt first, RanIt last, std::random_access_iterator_tag)
            {
                for (; first < last; ++first)
                    (swap)(*first, *--last);
            }
        };
     
        Aux()(first, last, typename std::iterator_traits<BidirectionalIterator>::iterator_category());
    }

Автор: Flex Ferrum 09.10.09, 10:51
Цитата Masterkent @
причём, по-моему, не было бы никакого смысла делать такой шаблон локальным.

В таком случае - да. Но... :huh:

Цитата Masterkent @
Можно сделать Processor закрытым членом Foo.

Можно. Но это значит вносить изменения в интерфейс класса, что (в ряде случаев, да и вообще) некомильфо. А локальный класс (в данном случае) никуда, кроме функции (в которой объявлен) не "выглядывает".

Цитата Masterkent @
Тут, кстати, видна другая проблема: шаблонными аргументами нельзя передавать имена функций. Довольно неприятное ограничение.

Угумс. Именно эту проблему и есть желание обойти. Указанным мною образом.

Автор: Masterkent 09.10.09, 11:17
Цитата Flex Ferrum @
Но это значит вносить изменения в интерфейс класса

Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO.

Автор: Flex Ferrum 09.10.09, 11:26
Цитата Masterkent @
Публичного интерфейса класса это почти не касается, поэтому проблема второсортная, IMHO.

Зато приведет к перекомпиляции зависимого от интерфейса кода. А это уже хуже.

Автор: Masterkent 09.10.09, 11:35
Цитата Flex Ferrum @
Зато приведет к перекомпиляции зависимого от интерфейса кода.

Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace.

Автор: Flex Ferrum 09.10.09, 11:36
Цитата Masterkent @
Если эта проблема критична, то можно поместить данный вспомогательный класс в unnamed namespace.

Да много чего можно то. :)

Автор: Masterkent 09.10.09, 11:43
Цитата Flex Ferrum @
Да много чего можно то.

О том и речь: есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно.

Автор: Flex Ferrum 09.10.09, 11:48
Цитата Masterkent @
есть масса неплохих workaround-ов, так что оснований для пересмотра правил здесь может быть недостаточно.

Но удочку закинуть все равно можно.

Автор: Flex Ferrum 09.10.09, 12:03
Цитата Masterkent @
В смысле?

В смысле, поинтересоваться мнением общественности по этому поводу где-нибудь в comp.std.c++

Автор: olias 12.10.09, 11:48
Цитата mas912 @
Самое последнее, что я видел, это C++ Library Working Group Status Report (Post San Francisco 2008) (N2870

This project was cancelled by SC22 in September 2008 - на главной странице комитета. Весь TR2 отменили, кроме decimal floating point arithmetic.

Автор: Большой 13.10.09, 11:32
Я так понимаю из буста в новый стандарт перекочует shared_ptr.
Но интересно в каком пространстве имен он будет?
И в чем его основные отличия от unique_ptr?

Автор: archimed7592 13.10.09, 11:46
Цитата Большой @
Но интересно в каком пространстве имен он будет?

std

Цитата Большой @
И в чем его основные отличия от unique_ptr?

unique_ptr - это эволюция auto_ptr и к shared_ptr он практически никак не относится.

Автор: Бобёр 13.10.09, 11:47
т.е. они фактически дали auto_ptr-у правильное название?
интересно, а до алгоритмов типа remove_if у них руки дойдут?

Автор: archimed7592 13.10.09, 11:48
Цитата Бобёр @
т.е. они фактически дали auto_ptr-у правильное название?

Не совсем. Там решён ряд синтаксически-семантических проблем.


Цитата Бобёр @
интересно, а до алгоритков типа remove_if у них руки дойдут?

:lol:

Автор: Большой 13.10.09, 12:05
Цитата Бобёр @
remove_if


так подожди у них проблема вроде была с copy_if

Цитата archimed7592 @
unique_ptr - это эволюция auto_ptr и к shared_ptr он практически никак не относится.

Это я знаю они семантику перемещения на семантику копирования
переладили, но от шареда чем отличаются?

Автор: Flex Ferrum 13.10.09, 12:16
Цитата Большой @
но от шареда чем отличаются?

Тем, что не shared. :)

Автор: archimed7592 13.10.09, 12:24
Цитата Большой @
Это я знаю они семантику перемещения на семантику копирования
переладили, но от шареда чем отличаются?

Ты это не знаешь.
Во-первых, наоборот, семантику перемещения добавили, а не заменили, но её добавили по всей стандартной библиотеке, так что я не её имел ввиду.
Во-вторых, как я уже сказал, к shared_ptr он практически никак не относится. Проще было бы рассказать что такое shared_ptr и что такое unique_ptr, чем перечислять их отличия. Информацию и о том и о другом можно найти в документации Boost'а.

Автор: Flex Ferrum 13.10.09, 12:33
Цитата archimed7592 @
Информацию и о том и о другом можно найти в документации Boost'а.

По поводу unique_ptr'а ты там ничего не найдешь, ЕМНИП. unique_ptr в бусте есть только в interprocess, и выковырять его оттуда (безболезненно) практически анрил.

Автор: archimed7592 13.10.09, 12:57
Если честно, я точно не помню где я про unique_ptr proposal читал...

Автор: miksayer 13.10.09, 15:12
Цитата Бобёр @
интересно, а до алгоритмов типа remove_if у них руки дойдут?

а что там за проблемы были?

Автор: archimed7592 13.10.09, 15:30
Цитата miksayer @
а что там за проблемы были?

Имя не совсем соответствует действительности :). В реальности remove ничего не удаляет.

Автор: Большой 14.10.09, 06:13
Цитата archimed7592 @
найти в документации Boost'а.

да и в драфте есть, только лень читать было
думал может кто так скажет

Автор: olias 14.10.09, 06:44
Хех.

unique_ptr - пере/до-работанный auto_ptr, который deprecated, вместе со stringstream.
В двух словах - у unique_ptr семантика перемещения (объектом владеет только один умный указатель), а shared_ptr имеет семантику разделения (один объект могут иметь/разделять много умных указателей).

Из доработов первого:
- семантика перемещения (rvalue-references)
- deleter'ы (функции/функторы, отвечающие за удаление объекта: в комплекте идут delete и delete[], можно задавать собственные)
- поддержка конвертируемых типов с корректным удалением:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A{};
    struct B: A{};
    std::unique_ptr<A> p(new B()); // или вообще, unique_ptr<void>.
    p.reset(); // delete pB


По shared_ptr читайте в TR1/Boost.

Автор: Radagast 14.10.09, 06:57
а зачем нужно было депрекейтить stringstream? оО

Автор: Flex Ferrum 14.10.09, 06:58
Цитата Radagast @
а зачем нужно было депрекейтить stringstream? оО

Он давным давно такой, просто до сих пор не "отсохнет". :)

Автор: Крон 14.10.09, 07:02
А что за место него рекомендуют?

Автор: Flex Ferrum 14.10.09, 07:06
Цитата Крон @
А что за место него рекомендуют?

std::strstream. Но он (этот strstream) не умеет записывать в заранее выделенный буфер памяти. ;) По этому stringstream до сих пор жив. :)

Автор: archimed7592 14.10.09, 07:22
Ребят, вы ничего не путаете? Не знаю как с этим дела обстоят в С++09, но в С++03 как раз strstream был deprecated а stringstream во всю рекомендуемым и используемым.

Автор: Flex Ferrum 14.10.09, 07:23
Возможно путаем. :) Слишком похоже называются. :)

Автор: archimed7592 14.10.09, 07:25
Лень лезть в стандарт которого под рукой нет, но в MSDN именно strstream обзывают deprecated.

Автор: Flex Ferrum 14.10.09, 07:25
Кстати, в новом стандарте упоминания о strstream есть только в приложении D (compatibility features).

Автор: Qraizer 14.10.09, 08:02
Тоже лень-матушка одолела, но таки скажу, что strstream хоть никуда и не денется из соображений обратной совместимости, но и развиваться не будет (отсутствие wstrstream и вообще его шаблонности тому подтверждение), а stringstream-у не помешало бы опциональное совмещение владения буфера между собой и юзер-кодом.

Автор: Flex Ferrum 14.10.09, 08:03
Цитата Qraizer @
а stringstream-у не помешало бы опциональное совмещение владения буфера между собой и юзер-кодом

Угумс. Что подняло бы его применимость на порядок.

Автор: olias 14.10.09, 11:25
Radagast
Ну, вместо него <sstream>, там получше сделано и универсальнее.

Автор: olias 22.10.09, 22:56
Прошёл слух, что в gcc 4.5 добавили constexpr. Кто-то может подтвердить?

Автор: Flex Ferrum 23.10.09, 05:39
Цитата olias @
Прошёл слух, что в gcc 4.5 добавили constexpr. Кто-то может подтвердить?

В их табличке здесь и здесь ничего такого нет.

Добавлено
Судя по тестом, сия фишка находится в процессе добавления. Сама конструкция constexpr распознаётся, но, например, в параметрах шаблона вызов такой функции использовать нельзя. Хотя в качестве указания размерности массива - можно.

Автор: Flex Ferrum 23.10.09, 06:55
Т. е. (судя по еще некоторым тестам), сами constexpr-функции, переменные и типы описывать можно, а вот в включение их в обработку конструкции constant expression еще не сделали.

Автор: Большой 23.10.09, 07:29
archimed7592

Конкретно что нас ждёт именно по шаблонам в новом стандарте.

Автор: archimed7592 23.10.09, 08:43
Большой, конкретно Вам рекомендую поискать глазами слова "шаблон" и/или "template" в достаточно крупных подзаголовках в первом посте.

Автор: olias 23.10.09, 09:13
Flex Ferrum
Ага, спасибо.

Автор: Flex Ferrum 23.10.09, 09:18
Цитата olias @
Flex Ferrum
Ага, спасибо.

Можешь и сам потестировать. Взять gcc 4.5 (под винду) можешь здесь.

Автор: miksayer 23.10.09, 11:34
что такое constant expression? просветите, пожалуйста

Автор: archimed7592 23.10.09, 11:37
Цитата archimed7592 @
Generalized Constant Expressions
constexpr - новое ключевое слово.
Суть нововведения в том, что теперь, например, можно как размерность массива использовать результат, возвращенный ф-цией.
struct A
{
    constexpr A(int i) : val(i) { }
    constexpr operator int() { return val; }
    constexpr operator long() { return 43; }
private:
    int val;
};

template<int> struct X { };
constexpr A a = 42;
X<a> x; // OK: unique conversion to int
int ary[a]; // error: ambiguous conversion

Автор: olias 23.10.09, 20:14
А кто-то может пояснить New wording for C++0x lambdas (N2927)? В чём там отличие с предыдущей реализацией?

Автор: Masterkent 24.10.09, 07:13
Цитата olias @
В чём там отличие с предыдущей реализацией?

Решён ряд проблем, описанных в defect report-ах под номерами, перечисленными в секции "Resolved issues". Изменений в тексте черновика много, и описывать их долго.

Автор: olias 24.10.09, 07:44
А, ну меня больше интересовало, нет ли там breaking changes, как в случае с rvalue references.

Автор: Большой 15.12.09, 06:58
Кто сможет пояснить назаначение новых ключевых слов
axiom
late_check

Автор: Flex Ferrum 15.12.09, 07:02
Цитата Большой @
Кто сможет пояснить назаначение новых ключевых слов
axiom
late_check

Это из концептов. Можешь расслабиться - их не будет в новом стандарте.

Автор: Большой 15.12.09, 08:53
Flex Ferrum
gcc сейчас поддерживает
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    initializer_list

а где можно скачать последний драфт стандарта, а то похоже мой совсем устраел

Автор: Flex Ferrum 15.12.09, 09:06
Цитата Большой @
gcc сейчас поддерживает

Да.

Цитата Большой @
а где можно скачать последний драфт стандарта, а то похоже мой совсем устраел

здесь.

Автор: olias 15.12.09, 09:38
А constexpr ещё нет?

Автор: Большой 15.12.09, 10:12
Цитата Flex Ferrum @
Да.
Cool
Цитата Flex Ferrum @
здесь.
Спасибо
Мой на 60 страниц тяжелее :)

Автор: Flex Ferrum 15.12.09, 10:19
Цитата olias @
А constexpr ещё нет?

Не проверял. Судя по логам - нет.

Автор: miksayer 15.12.09, 16:35
Цитата Большой @
initializer_list

это чтобы можно было перегружать оператор = для такого случая:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeClass a = {1, 2, 3}

?

Автор: olias 15.12.09, 20:58
Да. В бусте эту идею эмулировали, в Boost.Assign.

Автор: D_KEY 15.12.09, 21:53
Цитата olias @
Да. В бусте эту идею эмулировали, в Boost.Assign.

Ну все-таки это вещи очень разные.

Автор: Masterkent 15.12.09, 23:37
Цитата miksayer @
это чтобы можно было перегружать оператор = для такого случая:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeClass a = {1, 2, 3}

?

Тут нет присваивания.

Автор: miksayer 16.12.09, 16:41
Цитата Masterkent @
Тут нет присваивания.

в каком смысле? а что тогда?

Добавлено
Цитата olias @
Да. В бусте эту идею эмулировали, в Boost.Assign.

а каким примерно образом эмулировали? а то я не очень себе представляю, как это возможно

Автор: Flex Ferrum 16.12.09, 18:18
Цитата miksayer @
в каком смысле? а что тогда?

Вызов конструктора.

Автор: olias 16.12.09, 19:53
miksayer
тут примеры. Не один-в-один, конечно, но похоже да и всяко удобнее, чем через промежуточный Си-массив.

Автор: D_KEY 16.12.09, 20:03
Цитата olias @
miksayer
тут примеры. Не один-в-один, конечно, но похоже да и всяко удобнее, чем через промежуточный Си-массив.

А зачем это вообще нужно? Что неужели сложно сделать push_back или insert? Вот std::initializer_list другое дело. Инициализация при конструировании действительно полезна.

Автор: olias 17.12.09, 08:36
D_KEY
То есть, вместо "vector<int> v; v += 1,2,3,7,8,9;" предлагаешь писать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(7); v.push_back(8); v.push_back(9);

?

Цитата D_KEY @
Вот std::initializer_list другое дело.

Понятно, что другое, но для него нужна поддержка компилятором, а она есть пока только в гцц.

Автор: Flex Ferrum 17.12.09, 08:37
Цитата D_KEY @
А зачем это вообще нужно? Что неужели сложно сделать push_back или insert?

Для инициализации статических или глобальных контейнеров - очень даже удобно.

Автор: D_KEY 17.12.09, 11:30
Цитата olias @
D_KEY
То есть, вместо "vector<int> v; v += 1,2,3,7,8,9;" предлагаешь писать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    vector<int> v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(7); v.push_back(8); v.push_back(9);

?

Во-первых, совершенно не вижу смысла писать все в одну строку.
Во-вторых, а что тебе не нравится?
В-третьих, можно и так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int t[] = {1,2,3,7,8,9};
    vector<int> v(t, t + sizeof(t));

Не вижу достаточных оснований менять семантику оператора.
И вообще, я не понимаю, для чего было разрешать перегрузку operator,(равно как и && и ||).

Автор: GoldFinch 17.12.09, 12:23
Цитата D_KEY @
я не понимаю, для чего было разрешать перегрузку operator,

для списков, и для DSL
например если надо задать список T, то можно использовать T[]
но если надо задать список разных типов - то очевидно лучший вариант - перегрузка ,
my_array a; a+=1,"2",complex(3,4);

насчет DSL - посмотри на boost.spirit, как там используется перегрузка , && ||

Автор: D_KEY 17.12.09, 12:28
Цитата GoldFinch @
но если надо задать список разных типов - то очевидно лучший вариант - перегрузка ,
my_array a; a+=1,"2",complex(3,4);

А для меня очевидно, что это не стоит изменения семантики. , - это такой же "оператор", как ;. Может и это следует разрешить перегружать?
Есть tuple в бусте и в новом стандарте.
И ничего страшного в:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    my_array a;
    a += 1;
    a += "2";
    a += complex(3,4);

Я не вижу. А код гораздо читабельнее(ибо семантика не меняется).

Автор: GoldFinch 17.12.09, 12:52
D_KEY, ты не видишь - другие видят; не знаешь зачем - другие знают.
; - в терминологии С++ это не оператор, читай стандарт
в С++ вообще много что надо изменить и добавить

Автор: D_KEY 17.12.09, 13:03
Цитата GoldFinch @
D_KEY, ты не видишь - другие видят; не знаешь зачем - другие знают.

Естественно.

Цитата
; - в терминологии С++ это не оператор, читай стандарт

Я в курсе ;) . Я кавычки не зря поставил.
Мне не ясно почему , можно перегружать.

Цитата
в С++ вообще много что надо изменить и добавить

:yes-sad:

Автор: GoldFinch 17.12.09, 13:47
D_KEY, не хочешь перегружать , - не перегружай, но другим-то зачем не давать?

поиск "operator(\s*),(\s*)\(" в boost/ показывает что перегрузка , используется в
assign, python, proto, spirit, test

Автор: D_KEY 17.12.09, 13:58
Цитата GoldFinch @
D_KEY, не хочешь перегружать , - не перегружай, но другим-то зачем не давать?

Так я говорю, давай перегрузим ; или ?:
Понимаешь, есть "необычные" "операторы", поведение которых строго определено и отличается от семантики вызова функции. То есть вводя перегрузку таких операторов ты меняешь их суть. В результате понять, что и в какой последовательности делает код не всегда представляется возможным.
К таким "операторам" относятся, например, запятая, ||, &&, ?:. Из них запрещен только ?:.

Автор: GoldFinch 17.12.09, 14:14
D_KEY, тебе знакомо понятие DSL?
Если например в моем DSL || обозначает параллельные прямые - о какой последовательности речь??

Автор: D_KEY 17.12.09, 14:17
Цитата GoldFinch @
D_KEY, тебе знакомо понятие DSL?
Если например в моем DSL || обозначает параллельные прямые - о какой последовательности речь??

Знакомо. Только в С++ нереально сделать нормальный DSL. "Внешний" DSL, в любом случае, лучше.

Автор: olias 17.12.09, 14:18
Цитата D_KEY @
И ничего страшного в … Я не вижу. А код гораздо читабельнее(ибо семантика не меняется).

Спорно. Как раз возможность использования разных сущностей в одном выражении очень удобна и читабельнее, чем написанная "в столбик", sqlite++ тому примером. Да и потоки тоже из той же серии, с ними тоже в строчку удобнее выводить, чем "cout.write("hello, "); cout.write(name);"

ЗЫ а вообще, это всё оффтоп и его, наверное, надо вынести из данной темы.

Автор: D_KEY 17.12.09, 14:21
Цитата olias @
Цитата D_KEY @
И ничего страшного в … Я не вижу. А код гораздо читабельнее(ибо семантика не меняется).

Спорно. Как раз возможность использования разных сущностей в одном выражении очень удобна и читабельнее, чем написанная "в столбик"

Во-первых, я тебе привел вариант инициализации через массив. Во-вторых, ты все правильно говоришь для случаев, когда не меняется семантика и порядок вычислений(как в этом случае).
Цитата
sqlite++ тому примером. Да и потоки тоже из той же серии, с ними тоже в строчку удобнее выводить, чем "cout.write("hello, "); cout.write(name);"
Здесь с порядком вычислений все в порядке. Он соответствует неперегруженному варианту.

Автор: Qraizer 17.12.09, 14:58
D_KEY, верно, что перегруженные operator||(), operator&&() и operator,() имеют иную семантику. Потому их и не рекомендуется перегружать. Но это не достаточно сильное обоснование для полного запрета. Тот же ?: запрещён к перегрузке по иным соображиям.

Автор: D_KEY 17.12.09, 15:02
Цитата Qraizer @
Но это не достаточно сильное обоснование для полного запрета.

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

Цитата
Тот же ?: запрещён к перегрузке по иным соображиям.
По каким?

Автор: GoldFinch 17.12.09, 15:58
D_KEY
http://www.research.att.com/~bs/bs_faq2.html#overload-dot
Цитата
There is no fundamental reason to disallow overloading of ?:. I just didn't see the need to introduce the special case of overloading a ternary operator. Note that a function overloading expr1?expr2:expr3 would not be able to guarantee that only one of expr2 and expr3 was executed.


Добавлено
и да, действительно сложно представить зачем перегружать ?:

Автор: D_KEY 17.12.09, 16:20
Цитата GoldFinch @
и да, действительно сложно представить зачем перегружать ?:

То есть единственной причиной по которой нельзя перегружать ?: является отсутствие смысла? Мда... А до того, что порядок вычислений меняется, никому дела нет? Не знаю. На мой взгляд, перегрузка операторов, которые не могут быть представлены, как вызов функции, противоречит как смыслу перегрузки, так и реализации этого механизма... Ладно, действительно, не в тему спор.

Автор: Qraizer 17.12.09, 16:42
GoldFinch, в том-то и дело, что к трём остальным операторам это относится в той же мере. Все эти (неперегруженные) операторы вносят точку следования наравне с ;, чего не делают перегруженные, что и есть иной семантический смысл.
Не знаю точно. Могу догадываться, что возникают сложности с его интерпретацией в роли метода класса. Где там this-у место?

Автор: amk 17.12.09, 16:43
Тут скорее причина в другом, оператор ?: стоит несколько особняком от остальных операторов. Это скорее даже не оператор, а особая синтаксическая конструкция, вроде сокращенной записи для if…else.

В том же Algol W в этом качестве можно использовать if…fi. Там в этом смысле вообще хорошо, любая конструкция является выражением, возвращающим значение.

Автор: D_KEY 17.12.09, 17:41
Цитата amk @
Тут скорее причина в другом, оператор ?: стоит несколько особняком от остальных операторов.

Также, как и ||, && и, тем более, запятая.

Цитата
Это скорее даже не оператор, а особая синтаксическая конструкция, вроде сокращенной записи для if…else.
Ну не совсем. Это именно выражение, в отличие от.

Автор: amk 17.12.09, 23:33
Просто для ||, && и , нет такого устойчивого стереотипа, что они означают (по крайней мере у разработчиков стандартов такой стереотип видимо есть). Плюс можно их перегрузить чтобы они были более-менее понятны.

Хотя на мой взгляд лучше для первых двух операторов просто задать преобразователь в bool (вроде стандартный ), а для запятой, во избежание ненужных сюрпризов, пользоваться встроенным оператором.

Автор: D_KEY 17.12.09, 23:38
Цитата amk @
Просто для ||, && и , нет такого устойчивого стереотипа, что они означают

Дело не только в значении, дело в поведении и порядке вычислений.
Так, например, встроенный || не вычисляет второй аргумент, если первый - true, кроме того, первый аргумент всегда вычисляется до второго. А если мы перегружаем ||, то вычислены будут оба аргумента, причем в неизвестном порядке.

Автор: amk 18.12.09, 01:35
Да, это проблема. Если бы можно было отложить вычисление параметров до того момента, когда они действительно понадобятся. Но в C++ такой возможности нет - это не Алгол.

Автор: GoldFinch 18.12.09, 06:20
Цитата amk @
Если бы можно было отложить вычисление параметров до того момента, когда они действительно понадобятся.

ленивые вычисления вполне реализуемы, правда вместо foo(x) будет чтото вроде bind(foo,x)

Автор: D_KEY 18.12.09, 06:31
Цитата amk @
Да, это проблема. Если бы можно было отложить вычисление параметров до того момента, когда они действительно понадобятся. Но в C++ такой возможности нет - это не Алгол.

Так вот и незачем перегружать операторы, которые семантически нельзя представить в виде функций.

Автор: Qraizer 18.12.09, 17:10
D_KEY, нельзя заставлять поступать так-то и так-то исключительно из религиозных соображений. Тогда уж надо запретить перегружать + как умножение, префиксный ++ как постфиксный итп. Это было бы полезнее. Формальных же препятствий к перегрузке этих операций нет.

Автор: kanes 18.12.09, 17:16
Цитата D_KEY @
Так вот и незачем перегружать операторы, которые семантически нельзя представить в виде функций.

Кстати где-то видел такую рекомендацию: перегрузку операторов делать так: написать функцию, которая выполняет тоже самое, что и перегружаемый оператор, потом внутри перегрузки использовать эту функцию, честно говоря, не очень понимаю смысла сей рекомендации

Автор: D_KEY 19.12.09, 18:53
Цитата Qraizer @
D_KEY, нельзя заставлять поступать так-то и так-то исключительно из религиозных соображений.

Это не религиозные убеждения. Перегрузим ;?
Если бы в С++ был способ перегрузить эти операторы и сохранить порядок вычислений, то я бы не был против такой перегрузки.

Цитата
Тогда уж надо запретить перегружать + как умножение, префиксный ++ как постфиксный итп.

Во-первых, это невозможно. Во-вторых, перегрузка этих операторов не оказывает влияние на порядок выполнения.

Добавлено
Цитата kanes @
Цитата D_KEY @
Так вот и незачем перегружать операторы, которые семантически нельзя представить в виде функций.

Кстати где-то видел такую рекомендацию: перегрузку операторов делать так: написать функцию, которая выполняет тоже самое, что и перегружаемый оператор, потом внутри перегрузки использовать эту функцию, честно говоря, не очень понимаю смысла сей рекомендации

Возможно это касалось виртуальных методов. Вроде перегрузки оператора вывода(то есть сдвига ;)). Обычно пишется отдельный виртуальный метод, а оператор переопределяется для ссылки на базовый класс.

Автор: GoldFinch 19.12.09, 19:59
Цитата D_KEY @
Перегрузим ;?

говорили уже, что ; - не оператор. пробел перегрузи.

Автор: D_KEY 19.12.09, 20:17
Цитата GoldFinch @
Цитата D_KEY @
Перегрузим ;?

говорили уже, что ; - не оператор. пробел перегрузи.

Так и я о том. Перегружать , также глупо.

Добавлено
GoldFinch, ты просто рассматриваешь С++ как некую данность, я же хочу понять почему(и зачем) он такой. Пару лет назад, такие книги, как D&E, давали мне нужные ответы, но теперь мне этого недостаточно.
Но тут это все-таки не совсем в тему ;)

Добавлено
Разве можно сказать, что перегрузка , || && вообще является таковой? Их встроенные версии не являются простыми операторами(они вообще по сути своей не являются операторами, хотя и носят такое название), это специальные языковые формы и их нельзя имитировать другими средствами языка. Их "перегрузка" является введением совершенно иной сущности(нового оператора), но с тем же обозначением. Но в С++ нельзя определять собственные операторы, соответственно, даже с этой стороны, такие перегрузки противоречат идеологии языка...

Автор: GoldFinch 20.12.09, 09:07
D_KEY, точно также перегрузка << для потоков меняет сущность оператора сдвига,
а также перегрузка % в boost.format, перегрузка & в boost.serialization, и еще куча перегрузок меняющих семантику операторов.

Автор: kanes 20.12.09, 09:27
GoldFinch, сущность поменять можно, но не до абсурда, типа того что перегруженный << на самом деле работает как >> или + работает как умножение

Автор: sfinae 20.12.09, 10:21
Мне показалось что D_KEY делал упор не на изменение семантики самой операции, а на изменение семантики в контексте C++ (из-за изменения порядка выполнения).
Например код (который пишут некоторые мои знакомые):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    foo() && bar();

По сути эквивалентен
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if(foo())bar();

и гарантирует что bar будет вызван только в случае успешного выполнения foo().
А если для возвращаемого значения bar() перегрузить оператор &&, то эти функции уже могут быть вызваны в любом порядке, и уже к результату применен оператор &&. А это уже не так безобидно как умножать по значку "+".

Автор: D_KEY 20.12.09, 11:05
Цитата GoldFinch @
D_KEY, точно также перегрузка << для потоков меняет сущность оператора сдвига

Не точно также. << как был оператором, так им и остался, порядок вычисления и приоритет будет тем же. || && , ?: - "операторами", в принципе, не являются, поскольку управляют последовательностью вычислений. Это специальные языковые формы. Да, я знаю, что в стандарте они значатся, как операторы.
Их "перегрузка" таковой не является, поскольку в этом случае ты вводишь уже "настоящий" оператор(в отличие от встроенных версий || && , ?: ), который просто обозначается теми же символоми. Но это совершенно другая языковая конструкция. Ну не перегрузка это.

Добавлено
Цитата kanes @
GoldFinch, сущность поменять можно, но не до абсурда, типа того что перегруженный << на самом деле работает как >> или + работает как умножение

Это так. Но я не о том :)

Добавлено
Цитата sfinae @
Мне показалось что D_KEY делал упор не на изменение семантики самой операции, а на изменение семантики в контексте C++ (из-за изменения порядка выполнения).

Ага, примерно так.

Автор: доцент 22.12.09, 10:22
Может кто-нибудь объяснить почему опять убрали хэш-контейнеры из нового стандарта.

Автор: archimed7592 22.12.09, 10:28
Если я не ошибаюсь, то их никуда не убирали. Они присутствуют в TR1, который, насколько я понимаю, полностью был включен в стандарт. Называются они unordered_xxx

Автор: D_KEY 22.12.09, 12:39
Цитата Masterkent @
t + sizeof(t) тут не сгодится. Здесь можно было бы использовать boost::end:

Извиняюсь :blush: . Поторопился ;) .

Цитата
Они вполне себе операторы. Операнды у них есть? Есть. Выражения они образуют? Образуют. Чего ещё надо?

А можно определение операнда? Просто в контексте С++ у встроенных версий этих операторов операндов нет, поскольку операнды вычисляются до выполнения операции, а для этих операций это не так.

Цитата
Цитата D_KEY @
Их "перегрузка" является введением совершенно иной сущности(нового оператора), но с тем же обозначением.

Вообще-то оператор - это и есть обозначение:

Цитата ISO/IEC 24765:2008 (Systems and software engineering — Vocabulary)
operator. a mathematical or logical symbol that represents an action to be performed in an operation


Правильно. Только встроенные версии рассматриваемых "операторов" не являются операциями(фактически ведут себя как выражения). Или я опять ошибаюсь?

Цитата
Цитата
Но в С++ нельзя определять собственные операторы

Нельзя вводить новые обозначения и менять приоритеты. Перегрузка операторов не вводит новых обозначений и приоритеты не меняет.

А порядок вычислений менять и заставлять вычислять то, что встроенные версии не вычисляют, можно ;) ?

Автор: D_KEY 22.12.09, 14:28
Цитата Masterkent @
Цитата D_KEY @
А можно определение операнда?

В ISO/IEC 24765:2008 даётся такое определение:
Цитата
operand. a variable, constant, or function upon which an operation is to be performed

И я о том.
Цитата
Но в C++ операнды не ограничиваются только переменными, константами и функциями. Это могут любые выражения и даже типы.

То есть операндом в С++ может являться непосредственно само выражение? Как написать такую функцию?

Цитата
Цитата D_KEY @
поскольку операнды вычисляются до выполнения операции

Где такое правило сформулировано?

То есть при вызове функций(или операторов) операнды не обязаны быть вычислены до вызова?

Цитата
Цитата ISO/IEC 24765:2008
operation. (1) in computer mathematics, the action specified by an operator on one or more operands; (2) in programming, a defined action that can be performed by a computer system

К примеру, вот оно описание действия встроенного оператора &&:

Цитата 5.14
The operands are both implicitly converted to type bool (clause 4). The result is true if both operands are true and false otherwise. Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

The result is a bool. All side effects of the first expression except for destruction of temporaries (12.2) happen before the second expression is evaluated.

Что тут не нравится?

То, что это описание "операции" && не соответствует bool * bool -> bool(как должно быть согласно определению "the action specified by an operator on one or more operands"). Вообще, and может быть реализован, как операция над двумя операндами типа bool. Но встроенная версия себя так не ведет.
Я не против встроенного поведения, я говорю о том, что перегрузка таких операторов отличается от прочих перегрузок тем, что встроенные версии данных операторов являются специальными языковыми формами, а не обычными операциями(и не могут быть ими заменены). А в результате перегрузки мы вводим именно операцию.

Автор: sfinae 22.12.09, 14:33
Цитата Masterkent @
Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.

Вот собственно и описан предмет возмущения D_KEY.

Автор: Qraizer 22.12.09, 23:20
Это-то было понятно с самого начала. Непонятно, с чего бы это должно было быть причиной запрета на их перегрузку.
Возможность их перегрузки для пользовательских типов может быть полезна в ряде случаев. Тот факт, что будучи перегруженными, эти операторы будут иметь семантику, отличную от их стандартных форм, во-первых, несложно документируется, во-вторых, и без документирования вполне очевидна. Я склонен считать, что наоборот, стандартные формы этих операторов имеют особенную семантику, что и задокументировано Стандартом.

Автор: amdei 23.12.09, 00:58
Цитата Qraizer @
Я склонен считать, что наоборот, стандартные формы этих операторов имеют особенную семантику

Тем более только для типа bool.

Автор: D_KEY 23.12.09, 07:54
Цитата Qraizer @
Это-то было понятно с самого начала. Непонятно, с чего бы это должно было быть причиной запрета на их перегрузку.

Я не говорю, что нужно запретить. Я не понимаю, зачем было изначально разрешать. Обратной дороги уже нет. Как и со спецификациями исключений и многим другим...

Цитата
Возможность их перегрузки для пользовательских типов может быть полезна в ряде случаев.

В каких?

Цитата
Тот факт, что будучи перегруженными, эти операторы будут иметь семантику, отличную от их стандартных форм

А я пытаюсь сказать, что встроенные версии вообще не являются операторами.

Цитата
Я склонен считать, что наоборот, стандартные формы этих операторов имеют особенную семантику
Так и есть. Стандартные версии - особая языковая форма, а не оператор. Зачем понадобилось давать возможность "пользователям" создавать еще и оператор с таким же обозначением, как встроенная в язык особая форма - непонятно. Это все-равно, что разрешить перегружать макрос функцией.
Можно разрешить добавлять оператор ; или оператор пробела или operator".
А что? Просто "стандартные формы этих операторов" будут иметь "особенную семантику".

Автор: D_KEY 23.12.09, 17:00
Цитата Masterkent @
Цитата D_KEY @
Как написать такую функцию?

При чём тут функции? :wacko:

Можно тогда, на всякий случай, определение функции?
А там посмотрим.

Цитата Masterkent @
Цитата D_KEY @
То, что это описание "операции" && не соответствует bool * bool -> bool

Я не понимаю смысл такой формулировки.

Математическая запись бинарной операции.

Автор: D_KEY 24.12.09, 13:07
Цитата Masterkent @
Цитата D_KEY @
Математическая запись бинарной операции.

Ты можешь внятно растолковать смысл фразы "это описание "операции" && не соответствует bool * bool -> bool"? Составить предложение из букв и прочих символов - не значит написать что-то осмысленное.

Если ты не в состоянии что-либо понять, это вовсе не означает, что это что-либо не имеет смысла. Цитирование стандартов не всегда означает понимание лежащих в их основе концепций.
Функция, оператор и операция - это, в общем случае, отображения одного множества в другое.
Это понятие из математики, но оно справедливо и для программирования, пусть и с некоторыми оговорками для некоторых языков
(в данном случае, поскольку мы говорим об элементарных операциях, эти оговорки можно не учитывать).
Запись A -> B обозначает отображение множества A в множество B, то есть соответствие каждому из элементов множества A определенному элементу из множества B.
A*B обозначает пару элементов множеств A и B соответственно.
bool * bool -> bool – обозначает отображение(функцию, операцию, оператор), которое ставит в соответствие паре элементов из множества булевых значений элемент из множества булевых значений.
Если в язык встроены ленивые вычисления, а побочных действие нет, то отказ от вычисления второго аргумента логического and абсолютно естественен и по-прежнему соответствует bool * bool -> bool.
Если же в язык ленивые вычисления не встроены, но язык предоставляет некоторую специальную языковую конструкцию, которая позволяет откладывать вычисления на тот момент, когда потребуется значение (в принципе, при наличии лямбда функций такая форма имеет очень простую реализацию(но требует или хорошо развитых макросов или введение специальной языковой формы)), то указанное обозначение продолжает иметь силу, правда с некоторыми оговорками. С++ же не имеет ни того, ни другого. Да и не в этом дело.
В С++ операции и функции слишком часто используются для своих побочных эффектов, а не только для вычисления значения. Дело не только в "the second operand is not evaluated if the first operand is ...", а в sequence point.
Цитата
operators can be regrouped according to the usual mathematical rules only where the operators really
are associative or commutative
. . .
Overloaded operators are never assumed to be associative or commutative

Цитата
A full-expression is an expression that is not a subexpression of another expression

There is a sequence point at the completion of evaluation of each full-expression.

Но для рассматриваемых операторов мы имеем:
Цитата
In the evaluation of each of the expressions
a && b
a || b
a ? b : c
a , b
using the built-in meaning of the operators in these expressions (5.14, 5.15, 5.16, 5.18), there is a sequence point after the evaluation of the first expression.

Это и есть то, что называется особой формой.
Данные операции представляют собой специальные выражения, которые рассматриваются особым, отличным от предусмотренного для других выражений, образом.
Но, выполняя перегрузку, мы, естественно, убираем эту sequence point:
Цитата
When one of these operators is overloaded
(clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation,
and the operands form an argument list, without an implied sequence point between them

Мне кажется нелогично разрешать такую перегрузку.
Кроме того, logical AND он и есть logical AND, и смысла ни для каких значений, кроме bool'ов, не имеет.

Автор: D_KEY 24.12.09, 14:47
Цитата Masterkent @
Цитата D_KEY @
Функция, оператор и операция - это, в общем случае, отображения одного множества в другое.

Не в общем случае, а только в определённых разделах математики. В императивных языках программирования функции и операторы могут приводить к изменению состояния программы и не иметь результирующего значения.

Мы сейчас говорим о выражениях и встроенных операторах или где?

Цитата
Или, по-твоему, алгебраические определения - единственно верные и на них нужно молиться?

Нет. Молиться на какие-либо определения не стоит. Ни на "алгебраические", ни на указанные в стандартах. Но нужно понимать, откуда идут определенные понятия. И поскольку мы говорим о выражениях и элементарных операциях, то все мною сказанное остается корректным.

Цитата
Цитата D_KEY @
Мне кажется нелогично разрешать такую перегрузку.

А мне так не кажется.

Так что ты скажешь относительно sequence point?

Цитата
Цитата D_KEY @
Кроме того, logical AND он и есть logical AND, и смысла ни для каких значений, кроме bool'ов, не имеет.

Перегруженный оператор && не обязан вычислять "логическое И".
Как называется && в стандарте?
Но, конечно, не обязан.

Автор: Radagast 24.12.09, 17:10
Цитата
Здесь в полном соответствии со стандартом реализация имеет право вычислить f() во время выполнения программы

эээ почему? о_О разве приведенная строка не подпадает под
Цитата
Unlike &, && guarantees left-to-right evaluation: the second operand is not evaluated if the first operand is false.
?

Автор: D_KEY 25.12.09, 11:28
Цитата Masterkent @
Цитата D_KEY @
Мы сейчас говорим о выражениях и встроенных операторах или где?

Я ответил на конкретное предложение, где ничего не говорилось про выражения, но говорилось про операторы (без "встроенные"). Я не могу читать твои мысли, а могу только отвечать на то, что ты пишешь.

Но сохранять контекст разговора все-таки неплохо бы научится.

Цитата
очевидно... тоже очевидно.

Ну раз очевидно, тогда откуда высказывания о неуместности определений из математики?

Цитата
Я вообще не понимаю твои рассуждения.

Еще разок. Поведение встроенных , && || ?: сильно отличается от поведения остальных операторов, они представляют собой особые языковые формы. Их поведение нельзя имитировать другими языковыми средствами и при их перегрузке нельзя не исказить предусмотренной для них семантики.

Цитата
Скажу, что не вижу никаких доводов, почему отсутствие sequence point между вычислением аргументов операторной функции мешает перегрузке &&.
Потому, что нельзя создать перегрузку, которая будет сохранять семантику встроенной версии.

Цитата
Здесь в полном соответствии со стандартом реализация имеет право вычислить f() во время выполнения программы

Хм... Это несколько меняет дело... Правда в еще более худшую сторону. Неужели С++ настолько непредсказуем с точки зрения стандарта?

Автор: D_KEY 25.12.09, 13:54
Цитата Masterkent @
Цитата D_KEY @
Еще разок. Поведение встроенных , && || ?: сильно отличается от поведения остальных операторов, они представляют собой особые языковые формы. Их поведение нельзя имитировать другими языковыми средствами и при их перегрузке нельзя не исказить предусмотренной для них семантики.

Несколько утверждений и ни одного логического следствия. Так рассуждения не строятся.

Извини, не по стандарту.
"Следствия" были ранее. Я в очередной раз пытался обосновать свои тезисы о нелогичности перегрузки этих операторов. Интересно, слово "этих" будет понятно? На всякий случай скажу, что под "этими операторами" понимаются && || , ?:.

Автор: Qraizer 25.12.09, 18:31
Нелогично - перегружать без достаточных на то оснований. Но ещё более нелогично запрещать их перегрузку. Тоже нет достаточных оснований.

Автор: Большой 28.12.09, 09:39
Flex Ferrum
подскажи пожалуйста как использовать алгоритмы С09 в gcc

Автор: Flex Ferrum 28.12.09, 09:46
Цитата Большой @
подскажи пожалуйста как использовать алгоритмы С09 в gcc

Какие именно?

Автор: Большой 28.12.09, 11:35
ну copy_if например
я глянул вроде бы все есть, но не подключаются, я так думаю нужек ключ для компилятора

Автор: MyNameIsIgor 28.12.09, 12:05
Большой, gcc? Тогда -std=c++0x

Автор: Большой 28.12.09, 13:27
MyNameIsIgor
так не пашет

Автор: Flex Ferrum 28.12.09, 13:37
Цитата Большой @
MyNameIsIgor
так не пашет

В смысле?

Автор: Большой 29.12.09, 06:54
Flex Ferrum
Пардон, это что-то я тупанул

Автор: Masterkent 07.01.10, 22:07
Похоже, в C++0x наконец-то решили запретить неявное преобразование строкового литерала в указатель с потерей константности:

DR 693:
Цитата
Notes from the July, 2009 meeting:

The CWG reached consensus that the deprecated conversion should be removed altogether.

Proposed resolution (September, 2009):

1. Remove 4.2 [conv.array] paragraph 2:

A string literal (2.14.5 [lex.string]) with no prefix, with a u prefix, with a U prefix, or with an L prefix can be converted to an rvalue of type “pointer to char”, “pointer to char16_t”, “pointer to char32_t”, or “pointer to wchar_t”, respectively. In any case, the result is a pointer to the first element of the array. This conversion is considered only when there is an explicit appropriate pointer target type, and not when there is a general need to convert from an lvalue to an rvalue. [Note: this conversion is deprecated. See Annex D [depr]. —end note] For the purpose of ranking in overload resolution (13.3.3.1.1 [over.ics.scs]), this conversion is considered an array-to-pointer conversion followed by a qualification conversion (4.4 [conv.qual]). [Example: "abc" is converted to “pointer to const char” as an array-to-pointer conversion, and then to “pointer to char” as a qualification conversion. —end example]

[...]

4. Change the discussion of 2.14.5 [lex.string] in C.1.1 [diff.lex] as follows:

Change: String literals made const
The type of a string literal is changed... “array of const wchar_t.”

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    char* p = "abc";   // valid in C, invalid in C++

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

Автор: B.V. 19.02.10, 14:08
Читал, что FuturePack что-то там добавлял по C++ 0x в VC++ 2008. А не известно, будет ли какое-то дополнение или обновление для полной поддержки нового стандарта 2008-й студией?

Автор: Flex Ferrum 19.02.10, 15:31
Цитата B.V. @
Читал, что FuturePack

А это что за зверь?

Автор: B.V. 19.02.10, 17:16
Это опечатка, а не зверь. Конечно, FeaturePack

Автор: Flex Ferrum 19.02.10, 17:23
Цитата B.V. @
Это опечатка, а не зверь. Конечно, FeaturePack

Если 2008-го года, то там от C++0x - только расширение STL из tr1. Больше ничего. Но мне, честно говоря, успешно удался эксперимент по прикручиванию 2010-го компиля к 2008-ой студии.

Автор: olias 19.02.10, 20:01
Цитата Flex Ferrum @
успешно удался эксперимент по прикручиванию 2010-го компиля к 2008-ой студии.

Симлинки на папку(-и), делов-то. Но в 2010 с этим ещё проще, там появились (давно пора) тулсеты и можно выбирать, чем ты хочешь компилировать.

Автор: Flex Ferrum 16.03.10, 12:15
Последние новости из комитета по стандартизации:

http://herbsutter.wordpress.com/2010/03/13/trip-report-march-2010-iso-c-standards-meeting/

Автор: Бобёр 17.03.10, 13:19
Цитата
C++0x could officially be published as soon as next year as ISO C++ 2011, and we can stop with the “x-is-hex” jokes and just start calling it C++11.

Ну.. хочется в это верить :yes:

Автор: Большой 06.05.10, 15:55
boost обновился :)

Автор: DEADHUNT 06.05.10, 17:36
Цитата Большой @
boost обновился

только вот это похоже не исправили https://svn.boost.org/trac/boost/ticket/3844 поэтому не получается использовать boost.thread в gcc с включенным C++0x, приходится вручную править заголовочный файл.

Автор: niXman 06.05.10, 18:24
Цитата DEADHUNT @
Цитата Большой @
boost обновился

только вот это похоже не исправили https://svn.boost.org/trac/boost/ticket/3844 поэтому не получается использовать boost.thread в gcc с включенным C++0x, приходится вручную править заголовочный файл.

замечал сей баг. но использую std::thread, там с этим нет проблем.
а что(как) править нужно?

Автор: DEADHUNT 06.05.10, 18:29
Цитата niXman @
замечал сей баг. но использую std::thread, там с этим нет проблем.
а что(как) править нужно?

там же что типа этого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #ifdef HAVE_RVALUE_REFERENCES
    ....
    #else
    ...
    #endif

значит надо добавить #undef соответствующий в начало заголовка.
только в стандартной библиотеке libstdc++ не реализовали std::this_thread::yield, в boost реализовали.

Автор: Flex Ferrum 07.05.10, 05:34
Цитата niXman @
но использую std::thread, там с этим нет проблем.

В gcc у него под виндой проблемы. Просто не компиляется. Хотя, возможно, с последнего раза, как я это пробовал - уже пофиксили.

Автор: MyNameIsIgor 07.05.10, 06:10
Flex Ferrum, на последней вашей сборке тоже не компилится. В thread есть такая директива препроцессора
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)

Как я понял, она есть false, и код с классом thread просто не существует при компиляции.

Автор: Flex Ferrum 07.05.10, 06:14
Цитата MyNameIsIgor @
Как я понял, она есть false, и код с классом thread просто не существует при компиляции.

Ну, одно из двух. Либо не поправили, либо есть некие ключи конфигурации, которые можно выставить (при сборке), чтобы это заработало.

Автор: MyNameIsIgor 07.05.10, 06:34
Цитата Flex Ferrum @
либо есть некие ключи конфигурации, которые можно выставить (при сборке)

При сборке MinGW?

Автор: Flex Ferrum 07.05.10, 06:43
Цитата MyNameIsIgor @
При сборке MinGW?

Ну да.

Автор: MyNameIsIgor 07.05.10, 06:47
Flex Ferrum, ясно. Значит, придётся ставить эксперименты самому :)

Автор: niXman 07.05.10, 16:03
Цитата MyNameIsIgor @
Flex Ferrum, на последней вашей сборке тоже не компилится. В thread есть такая директива препроцессора
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)

Как я понял, она есть false, и код с классом thread просто не существует при компиляции.

в каком файле?

Автор: MyNameIsIgor 07.05.10, 16:11
niXman, там же написано - во thread :)
Не помню точно путь в винде, но судя по линухе - includes/c++/4.5.0/thread

Автор: niXman 07.05.10, 17:27
Цитата MyNameIsIgor @
там же написано - во thread

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

Автор: ShapovalovTS 26.07.10, 04:15
Не до конца понимаю варианты использования lambda-функции в новом стандарте. Если я хочу объявить multimap с компаратором в виде lambda-функции, то по идее код будет примерно следующим:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct A {
            int i;
    };
     
    std::multimap<int, A,
            [](A a1, A a2) -> bool {return a1.i < a2.i; }
    > m;


Но компилятор (intel c++ 12 beta с ключём -std=c++0x), который запросто воспринимает lambda в других местах, в таком объявлении не понимает синтаксиса. Возможно ли такое использование lambda-функций?

Автор: MyNameIsIgor 26.07.10, 04:27
ShapovalovTS, аргументом шаблона должен быть тип компаратора, а данное выражение
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [](A a1, A a2) -> bool {return a1.i < a2.i; }

создаёт, как я понимаю, именно экземпляр лямбды. И, кстати, в данном случае не обязательно указывать возвращаемый лямбдой тип.
Для получения типа лямбды можно использовать decltype как-то так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [](A a1, A a2) {return a1.i < a2.i; };
    std::multimap<int, A, decltype(f)> m(f);

Поскольку для лямбд не гарантируется наличие конструктора по умолчанию, то мы передаём экземпляр лямбды в конструктор multimap'а.

Добавлено
Кстати, только сейчас заметил :) Компаратор то должен ключи сравнивать, т.е. int'ы в вашем случае, а у вас он сравнивает объекты типа A.

Автор: ShapovalovTS 26.07.10, 05:07
MyNameIsIgor, спасибо за ответ, в таком виде компилятор код воспринимает. Со сравнением int-ов - тоже верное замечание.

А есть ли в этом случае способ в новом стандарте заменить auto f на что-то типа typedef <lambda-expr> f; в объявлении класса, иначе приходится выносить этот код на уровень выше, чего делать не хотелось бы.

Автор: MyNameIsIgor 26.07.10, 05:18
Цитата ShapovalovTS @
А есть ли в этом случае способ в новом стандарте заменить auto f на что-то типа typedef <lambda-expr> f; в объявлении класса

Я немного не понял, что вы хотите сделать. В том то и дело, что тип лямбды нам неизвестен, потому typedef мы можем сделать только с использованием decltype
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [](A a1, A a2) {return a1.i < a2.i; };
    typedef decltype(f) some_type;

Если же вам нужно, чтобы тип компаратора был виден глобально, то больше смысла будет в создании функтора, так сказать, "по-старинке", а не в использовании лямбды. Всё же лямбда - это что-то для локального использования.

Добавлено
Или вы хотите в таком виде?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef decltype([](A a1, A a2) {return a1.i < a2.i; }) some_type;

Тут нужно знатоков стандарта, ибо я не знаю, законна ли такая конструкция в принципе. Но у меня в gcc 4.5 она не компилировалась.
И в таком случае не получится создать экземпляр этого типа. Т.е. код
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    some_type f;

не скомпилируется, потому что у лямбд нет конструктора по умолчанию.

Автор: ShapovalovTS 26.07.10, 05:39
Цитата MyNameIsIgor @

Или вы хотите в таком виде?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    typedef decltype([](A a1, A a2) {return a1.i < a2.i; }) some_type;


Да, хотелось бы не выносить тип из объявления класса, в котором идет работа с std::multimap. Мой компилятор от Intel тоже отказывается подобное компилировать:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class B {
        struct A {int i;};
     
        typedef decltype([](A a1, A a2) {return a1.i < a2.i; }) some_type;
    };

Автор: MyNameIsIgor 26.07.10, 08:12
ShapovalovTS, тогда я бы сделал так
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class B {
        struct A {int i;};
     
        struct comparator : public std::binary_function<A, A, bool>
        {
            bool operator() (const A& first, const A& second) const { return first.i < second.i; }
        };
        std::multimap<A, int, comparator> m;
    };

Автор: Flex Ferrum 26.07.10, 08:18
Эммм... Что-то вы не то и не с тем мешаете. :)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    // При объявлении типа мапы:
    typedef std::multimap<int, A, std::function<bool (A const&, A const&)>> mmap_type;
     
    // при объявлении экземпляра мультимапы:
    mmap_type m([](A a1, A a2) {return a1.i < a2.i; });

Как-то так.

Автор: MyNameIsIgor 26.07.10, 09:52
Flex Ferrum, я думал об этом. Но иметь полиморфный вызов для сравнения - не по плюсовому как-то ;)

Автор: Flex Ferrum 26.07.10, 09:55
Цитата MyNameIsIgor @
Flex Ferrum, я думал об этом. Но иметь полиморфный вызов для сравнения - не по плюсовому как-то ;)

А иначе то - никак. По большому счёту. Хотя (по последней редакции стандарта) должно работать так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
       // При объявлении типа мапы:
       typedef std::multimap<int, A, bool (*)(A a1, A a2)> mmap_type;
        
       // при объявлении экземпляра мультимапы:
       mmap_type m([](A a1, A a2) {return a1.i < a2.i; });

Т. е. в случае, если лямбла идёт без capture-списка, то должна спокойно приводиться к указателю на функцию с соответствующей сигнатурой.

Автор: MyNameIsIgor 26.07.10, 09:58
Цитата Flex Ferrum @
А иначе то - никак. По большому счёту.

А чем вариант с отдельным компаратором не устраивает?
Цитата Flex Ferrum @
Т. е. в случае, если лямбла идёт без capture-списка, то должна спокойно приводиться к указателю на функцию с соответствующей сигнатурой.

Но, опять же, на inline такого простейшего сравнения не приходится надеяться.

Автор: Flex Ferrum 26.07.10, 10:49
Цитата MyNameIsIgor @
А чем вариант с отдельным компаратором не устраивает?

Ну, это классика, которая уже перенесена в STL.

Добавлено
Цитата MyNameIsIgor @
Но, опять же, на inline такого простейшего сравнения не приходится надеяться.

Да как сказать... Вполне может заинлайнить.

Автор: MyNameIsIgor 26.07.10, 12:01
Цитата Flex Ferrum @
Ну, это классика, которая уже перенесена в STL.

В это же нет ничего плохого :)
Цитата Flex Ferrum @
Да как сказать... Вполне может заинлайнить.

Подумал... Да, может :)

Автор: ShapovalovTS 27.07.10, 03:01
Цитата Flex Ferrum @
Хотя (по последней редакции стандарта) должно работать так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
       // При объявлении типа мапы:
       typedef std::multimap<int, A, bool (*)(A a1, A a2)> mmap_type;
        
       // при объявлении экземпляра мультимапы:
       mmap_type m([](A a1, A a2) {return a1.i < a2.i; });

Интересное своей краткостью решение, но компилятор к сожалению ругается. Код (lambda.h):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <multimap.h>
     
    struct A {
        int i;
    };
     
    class B {
     
            typedef std::multimap<A, int, bool (*)(A, A)> mmap_type;
        
            mmap_type m;
     
            B() : m([](A a1, A a2) {return a1.i < a2.i; })  {
            }
    };

И сама ошибка:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    lambda.h(13): error: no instance of constructor "std::multimap<_Key, _Tp, _Compare, _Alloc>::multimap [with _Key=A, _Tp=int, _Compare=bool (*)(A, A), _Alloc=std::allocator<std::pair<const A, int>>]" matches the argument list
                argument types are: (lambda [](A, A)->bool)
            B() : m([](A a1, A a2) {return a1.i < a2.i; })  {
                   ^
     
    compilation aborted for lambda.cpp (code 2)

В случае приведения в строке 13 к mmap_type::key_compare получаем это:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    lambda.h(13): error: no suitable conversion function from "lambda [](A, A)->bool" to "bool (*)(A, A)" exists
            B() : m(mmap_type::key_compare([](A a1, A a2) {return a1.i < a2.i; }) ) {
                                           ^
     
    compilation aborted for lambda.cpp (code 2)

Получается, еще недореализовали стандарт в тестируемом мною компиляторе?

Автор: Flex Ferrum 27.07.10, 05:47
Цитата ShapovalovTS @
Получается, еще недореализовали стандарт в тестируемом мною компиляторе?

Такие изменения - только в последней редакции стандарта (конец марта 2010-го года). Очевидно, что ещё ни один компиль это не реализует. Да и не зафиксировано это ещё окончательно.

Автор: trainer 27.07.10, 06:02
Цитата Flex Ferrum @
в последней редакции стандарта
последней редакции предложения. Его же еще не приняли?

Автор: Flex Ferrum 27.07.10, 06:03
Цитата trainer @
последней редакции предложения. Его же еще не приняли?

Ну, да. :)

Автор: Flex Ferrum 13.08.10, 07:59
boost::variant? Проще некуда. :)

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<int I, typename ... T>
    union variant_data;
     
    template<int I, typename T, typename ... Tail>
    union variant_data<I, T, Tail ...>
    {
        T m_data;
        variant_data<I + 1, Tail ...> m_tail;
        
        variant_data() {;}
        ~variant_data() {;}
    };
     
    template<int I, typename T>
    union variant_data<I, T>
    {
        T m_data;
        variant_data() {;}
        ~variant_data() {;}
    };
     
    template<typename ... T>
    struct variant
    {
        int m_dataIdx;
        variant_data<sizeof ... (T), T ...> m_variantData;
    };

Автор: Masterkent 31.08.10, 00:53
Цитата Flex Ferrum @
Пока все идет к тому, что кроме концептов из стандарта ничего выкидывать не будут.

Похоже, из C++0x могут удалить ни кем пока не реализованные фичи.

User-defined literals
Ref-qualifiers
Inheriting constructors

Работа комитета по стандартизации C++ радует всё больше и больше. Что правила C++ там толком не знают ([1][2][3]) я уже выяснил давно. Что некоторые члены комитета плохо владеют логикой и не пригодны для составления корректных формальных описаний выяснилось сравнительно недавно [1][2][3][4]. Теперь ещё нелепая мотивация добавления правил и удаления фич добавилась к послужному списку.

Hint: D. Krugler, A. Williams и S. Clamage состоят в рабочих группах комитета по стандартизации C++.

Автор: Flex Ferrum 07.09.10, 18:31
Цитата Masterkent @
Похоже, из C++0x могут удалить ни кем пока не реализованные фичи.

User-defined literals
Ref-qualifiers
Inheriting constructors

Ну, тут бабушка ещё на двое сказала. Это предложение только одной из стран (если я правильно понимаю аббревиатуру). С этим должны согласиться большинство, чтобы быть принятым. А переколбашивать драфт стандарта перед самым принятием - это жесть.

Автор: Masterkent 08.09.10, 18:18
Цитата Flex Ferrum @
А переколбашивать драфт стандарта перед самым принятием - это жесть.

А когда состоится это самое принятие? Там по-любому ещё море исправлений надо внести - даже не считая те, которые пока не занесены в списки Core Language Active Issues и Library Active Issues.

Автор: Flex Ferrum 09.09.10, 05:48
Цитата Masterkent @
А когда состоится это самое принятие?

Ты намекаешь на то, что "никогда"? :huh: Хотя, судя по тому, как сейчас их встречи обставляются (читай agend'ы) - предположение недалеко от истины...

Автор: Masterkent 09.09.10, 10:36
Цитата Flex Ferrum @
Ты намекаешь на то, что "никогда"?

Скорее, на то, что новый стандарт или выйдет нескоро, или выйдет скоро, но в нём будет много-много дефектов (впрочем, их и в C++03 море). У меня всё никак руки не дойдут составить подробный отчёт о некоторых дефектах, о которых в комитете предположительно не знают, и отправить его в CWG. Пока я только время от времени создавал темы на comp.lang.c++.moderated и comp.std.c++. Лишь малую часть описанных мной проблем D. Krugler и D. Gregor направили на рассмотрение в CWG: 978, 1005, 1055, 1059, 1068, 1093. Первую проблему уже пофиксили, остальные пока рассматриваются или дожидаются рассмотрения.

Автор: Flex Ferrum 11.09.10, 16:33
gcc 4.6 обзавёлся range-based for loops...
Скрытый текст
качаем, компиляем, пробуем... :)

Автор: niXman 11.09.10, 17:19
уау!
пару дней назад смотрел - небыло.

Автор: Flex Ferrum 11.09.10, 17:58
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    int main()
    {
        int arr[] = {1, 2, 3, 4, 5};
        for (auto i: arr)
        {
            std::cout << i << " ";
        }
        std::cout << std::endl;
    }

выдаёт честные
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    P:\projects\tests\c++0x>a.exe
    1 2 3 4 5


Добавлено
Такой вариант:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
          #include <iostream>
          
          int main()
          {
              for (auto i: {1, 2, 3, 4, 5})
              {
                  std::cout << i << " ";
              }
              std::cout << std::endl;
          }

Тоже работает. :)

Автор: DEADHUNT 11.09.10, 20:00
Цитата Flex Ferrum @
Тоже работает.

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

Автор: D_KEY 11.09.10, 20:05
Цитата DEADHUNT @
Цитата Flex Ferrum @
Тоже работает.

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

В каком смысле? Я в линуксе собираю. Этот пример пока не пробовал(сейчас нет возможности).

Автор: niXman 11.09.10, 20:07
Цитата DEADHUNT @
возникают проблемы с запуском на других компьютерах(в частности в линуксе)

ложь ;)
я уже шесть месяцев работаю над проектом, на плюсах, с обильным использованием 0х. никаких сложностей нет. даже на мингве 4.5.1-4.6.0 все работает один в один.

Автор: DEADHUNT 11.09.10, 21:22
Цитата niXman @
ложь
я уже шесть месяцев работаю над проектом, на плюсах, с обильным использованием 0х. никаких сложностей нет. даже на мингве 4.5.1-4.6.0 все работает один в один.

да у себя на компе работает, но как перенести на другой компьютер где нет gcc 4.5+? бинарник требует stdlibc++ которой нет в системе(есть более старая версия).

Автор: niXman 11.09.10, 21:29
Цитата DEADHUNT @
но как перенести на другой компьютер где нет gcc 4.5+

установить.

Цитата DEADHUNT @
бинарник требует stdlibc++ которой нет в системе

к счастью, мне не приходилось переносить бинарники. всегда сорцы.
но даже с бинарниками не должно быть проблем. однажды маялся с такой проблемой. все просто решается, заданием значения переменной окружения LD_PRELOAD. если что, могу подробнее рассказать как это делается.

Автор: DEADHUNT 11.09.10, 21:34
Цитата niXman @
установить.

если ты делаешь какую-то программу, то пользователям чтобы её использовать надо gcc вместе с libstdc++ последней версии собирать из исходников?
Цитата niXman @
к счастью, мне не приходилось переносить бинарники. всегда сорцы.

все ровно нужен собранный gcc соответствующей версии.

Добавлено
если собирать gcc 4.4 то проблем с запуском в современных дистрибутивах не должно быть, т.к. в них установлен gcc 4.4 по умолчанию.

Автор: D_KEY 11.09.10, 22:18
DEADHUNT, мне кажется, что ты не совсем понимаешь, о чем говоришь. Но это тут не в тему :)

Автор: niXman 11.09.10, 22:40
Цитата DEADHUNT @
если ты делаешь какую-то программу, то пользователям

я не пишу прикладной софт, или такой, какой устанавливают _юзеры_.

Автор: amk 12.09.10, 03:56
Не понял, зачем устанавливать целиком g++, если нужна только библиотека. Она же вроде отдельно устанавливаться может. А не может сама, так можно вручную ее установить.

Просто в тех версиях Linux, что я сталкивался, эта библиотека всегда шла отдельной строкой.

Автор: DEADHUNT 12.09.10, 07:39
Цитата D_KEY @
DEADHUNT, мне кажется, что ты не совсем понимаешь, о чем говоришь. Но это тут не в тему

понимаю, просто мне уже приходилось ради переносимости переписывать с C++0x на C++.
Цитата amk @
Не понял, зачем устанавливать целиком g++, если нужна только библиотека. Она же вроде отдельно устанавливаться может. А не может сама, так можно вручную ее установить.

при сборке программы gcc версии x.x в бинарник автоматически добавляются зависимости от libstdc++ x.xyz(в винде это всё статически можно собрать, но в линуксе не получается), поэтому при сборке программы gcc 4.5, а потом при запуске например в чистой fedora 13 (где по умолчанию стоит gcc 4.4), загрузчик выдаст ошибку "установлена libstdc++ более низкой версии"

Автор: D_KEY 12.09.10, 09:00
Цитата DEADHUNT @
Цитата D_KEY @
DEADHUNT, мне кажется, что ты не совсем понимаешь, о чем говоришь. Но это тут не в тему

понимаю, просто мне уже приходилось ради переносимости переписывать с C++0x на C++.
Цитата amk @
Не понял, зачем устанавливать целиком g++, если нужна только библиотека. Она же вроде отдельно устанавливаться может. А не может сама, так можно вручную ее установить.

при сборке программы gcc версии x.x в бинарник автоматически добавляются зависимости от libstdc++ x.xyz(в винде это всё статически можно собрать, но в линуксе не получается), поэтому при сборке программы gcc 4.5, а потом при запуске например в чистой fedora 13 (где по умолчанию стоит gcc 4.4), загрузчик выдаст ошибку "установлена libstdc++ более низкой версии"

А пакет свой сделать на gcc и стандартную библиотеку никак?

Автор: amk 13.09.10, 01:25
Цитата DEADHUNT @
в бинарник автоматически добавляются зависимости от libstdc++
Видишь, libstdc++ у тебя тоже существует отдельно, иначе зависимость не нужна была бы, но это и означает, что библиотека может быть установлена отдельно

Автор: Painkiller 22.10.10, 08:09
Бинарник будет непереносим, хоя если не требуеться чтобы работало везеде то...

Автор: евгений_олегович 08.11.10, 07:43
мне кажется новый стандарт будет ужасный (в плане синтаксиса и восприятия кода и оставленных старых вещей позади) .
За погоней совместимости с программами написанными на С++99 новые возможности это чаще всего новые ключевые слова.

Вот допустим enum, новый enum class. Зачем спрашивается вводить еще одно ключевое слово. Нет чтобы данный enum сделать таким как должен работать enum class, а получается что если так сделать то скорее всего все пойдет в старых проектах через .опу. Поэтому только из за совместимости. При введение нового enum class, наверно никто уже старым пользоваться не будет, т.е старая версия enum будет болтаться просто так. Вроде бы и не мешает, а загромождает.

Да и вообще синтаксис нового стандарта, тоже не из лучших. Взять допустим rvalue - && 2 амперсанда это же дико. Не фига не читаем.

В общем, понятно, что мои возмущения это как в воздух пукать. Но все равно, могли бы что нибудь и по умнее придумать, для моего восприятия это еще куча новых слов и еще большая нечитаемость для &&, потом 3 введут в следующем стандарте что ли??. бррр

Автор: Flex Ferrum 08.11.10, 07:52
Цитата евгений_олегович @
Вот допустим enum, новый enum class. Зачем спрашивается вводить еще одно ключевое слово. Нет чтобы данный enum сделать таким как должен работать enum class, а получается что если так сделать то скорее всего все пойдет в старых проектах через .опу. Поэтому только из за совместимости. При введение нового enum class, наверно никто уже старым пользоваться не будет, т.е старая версия enum будет болтаться просто так. Вроде бы и не мешает, а загромождает.

Ага. Сделаешь так, а потом членов комитета будут линчевать на медленном огне за потерю совместимости со старым кодом. Страуструп про это очень красочно рассказывал. Требование обратной совместимости кода - очень жёсткое, и отступают от него только тогда, когда иначе сделать совсем никак нельзя.

Цитата евгений_олегович @
Но все равно, могли бы что нибудь и по умнее придумать, для моего восприятия это еще куча новых слов и еще большая нечитаемость для &&, потом 3 введут в следующем стандарте что ли??. бррр

Опять же процитирую Страуструпа (вольно): "Вы знаете как сделать это лучше? Я вам могу уступить своё место!"

На самом деле, с читаемостью кода всё нормально. Сначала да - немного непривычно, потом глаз "набивается", и всё становится нормально.

Автор: trainer 08.11.10, 08:35
Цитата евгений_олегович @
&& 2 амперсанда это же дико. Не фига не читаем.
&& || == //
Это только символы одиночных операций из двух одинаковых символов.

Автор: MyNameIsIgor 08.11.10, 09:34
Кстати, про новый стандарт. Правильно ли я понимаю, что теперь аллокаторы таки будут иметь состояние, т.е. пообъектную информацию?

Автор: Flex Ferrum 08.11.10, 10:39
Цитата MyNameIsIgor @
Правильно ли я понимаю, что теперь аллокаторы таки будут иметь состояние, т.е. пообъектную информацию?

В смысле?

Добавлено
Ага! В gcc 4.6 будут constexpr'ы! Ура, товарищи! :)

Автор: Radagast 08.11.10, 11:03
Цитата
В смысле?

я так понимаю, имелась в виду страница 363:
Цитата
Implementations of containers described in this International Standard are permitted to assume that their
Allocator template parameter meets the following two additional requirements beyond those in Table 32:
— All instances of a given allocator type are required to be interchangeable and always compare equal to each other.
...

Автор: Flex Ferrum 08.11.10, 11:15
Цитата Radagast @
я так понимаю, имелась в виду страница 363:

Ну так это цитата из действующего стандарта. Я, видимо, что-то не понимаю?

Автор: MyNameIsIgor 08.11.10, 11:22
Radagast, ага, так в текущем стандарте. А в новом есть, например, такое
Цитата 23.3.4.4 list operations /2
list provides three splice operations that destructively move elements from one list to another. The behavior
of splice operations is undefined if get_allocator() != x.get_allocator().

Только я ещё не разобрался с хитросплетениями allocator_traits, scoped_allocator и их использования контейнерами :) Думал, что кто-то уже всё понял и сможет объяснить :)

Добавлено
Flex Ferrum, дело всё в том, что в новом стандарте сравнение аллокаторов будет настоящим, а не бутафорским. Т.е. сравниваться будут именно экземпляры аллокаторов.

Автор: Flex Ferrum 08.11.10, 11:31
Цитата MyNameIsIgor @
Flex Ferrum, дело всё в том, что в новом стандарте сравнение аллокаторов будет настоящим, а не бутафорским. Т.е. сравниваться будут именно экземпляры аллокаторов.

Эммм... А в силу действующего стандарта оно было именно бутафорским? Ссылочки можно? :)

Автор: MyNameIsIgor 08.11.10, 11:34
Flex Ferrum, эммм... А каким? Ссылочку Radagast привёл. Все контейнеры опираются на то, что все экземпляры конкретного типа аллокатора взаимозаменяемы, т.е. их нет смысла сравнивать - они всегда равны друг другу. И в текущем стандарте нет оговорки, которую я привёл выше для splice.
Т.е. сейчас важен именно тип аллокатора. В новом стандарте важен и его экземпляр.

Автор: Flex Ferrum 08.11.10, 11:37
Цитата MyNameIsIgor @
Flex Ferrum, эммм... А каким? Ссылочку Radagast привёл. Все контейнеры опираются на то, что все экземпляры конкретного типа аллокатора взаимозаменяемы, т.е. их нет смысла сравнивать - они всегда равны друг другу. И в текущем стандарте нет оговорки, которую я привёл выше для splice.
Т.е. сейчас важен именно тип аллокатора. В новом стандарте важен и его экземпляр.

Да, точно. Что-то я туплю.

Сообщения были разделены в тему "зачистка диска"

Автор: Qraizer 04.04.11, 18:05
Ну что ж, уважаемые коллеги. Я вас всех поздравляю вот с этим событием. Сенкс niXman-у за ссылку.

Автор: niXman 04.04.11, 18:11
Qraizer, не за что. прими мои поздравления.
вообще-то, я сам сильно обрадовался. да так, что прикупил бутылочку хорошего вина, и со своей половинкой, вдвоем, мы это событие и отметили :whistle:

детальный список: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.200x

всем мои поздравления.

Автор: Flex Ferrum 05.04.11, 05:36
Ура, товарищи!

Добавлено
Тогда уж (до кучи): GCC 4.6 Released. Поддержка им новых фич стандарта перечислена здесь.

Автор: Алексей_Л 10.04.11, 15:47
А есть ли способ "подружить" Visual Studio 2010 с новым стандартом? Может быть будет обновление?
P.S. Понятно, что можно подключить другой компилятор (тот же gcc), но это уже шаманство.
P.P.S. Очень уж понравился новый обход контейнеров:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for(auto i : v)
          cout << i;

Автор: niXman 10.04.11, 15:49
Цитата Алексей_Л @
можно подключить другой компилятор

куда подключить? зачем?
используй mingw, если в венде работаешь.
я сегодня-завтра выложу сборку на базе 4.6.0.

Автор: Алексей_Л 10.04.11, 16:36
Да просто не хочется с Visual Studio переезжать.

Автор: niXman 10.04.11, 18:19
обновил :)
в подписи.

Автор: Алексей_Л 12.04.11, 12:40
Скачал последний MinGW с gcc, чудом нашёл про -std=c++0x.
Собралось... кое-что, ладно, списки инициализации, функции (function всмысле) работают и радуют глаз, но вот это:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for(auto i : v)
     cout << i;

Ругается:
Цитата

D:\Projects\CodeBlocks\ConsoleTest\main.cpp|18|error: expected initializer before ':' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected primary-expression before '}' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected ';' before '}' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected primary-expression before '}' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected ')' before '}' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected primary-expression before '}' token|
D:\Projects\CodeBlocks\ConsoleTest\main.cpp|20|error: expected ';' before '}' token|
||=== Build finished: 7 errors, 0 warnings ===|

Хотя тот же
Цитата niXman @
компилятор онлайн. теперь с поддержкой C++0x!

прекрасно такую конструкцию собирает. В чём проблема?
P.S. Регистрация на сайте LWS почему-то не работает (проверял и IE, и Opera, и Android'ом).

Автор: Flex Ferrum 12.04.11, 12:47
Цитата Алексей_Л @
Скачал последний MinGW с gcc, чудом нашёл про -std=c++0x.

Есть подозрение, что у niXman староватые исходники. ;) Потому как августовский-сентябрьский снапшот с этим кодом отлично справлялся. :)

Автор: niXman 12.04.11, 13:02
Цитата Алексей_Л @
Скачал последний MinGW с gcc

хз что ты качал. и главное - откуда!

этот код компилиться с полпинка и компилятором который в подписи, и на LWS:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <vector>
    #include <iostream>
     
    int main() {
       std::vector<int> vec({0,1,2,3,4,5,6,7,8,9}); // initializer list
       for ( int i: vec ) { // range based for
          std::cout << i << std::endl;
       }
    }

http://liveworkspace.org/code/b04e2469f83eab30c2979f0233a18456

Цитата Flex Ferrum @
у niXman староватые исходники

клевета! :D

Автор: Flex Ferrum 12.04.11, 13:03
Цитата niXman @
клевета! :D

:blush: Ну, извини, раз так. :)

Автор: niXman 12.04.11, 13:04
Цитата Алексей_Л @
Регистрация на сайте LWS почему-то не работает

то, что предоставляет регистрация - еще не законченно. но скоро...очень скоро..

Автор: Алексей_Л 12.04.11, 13:33
качал это:
mingw-get-inst-20110316.exe
http://sourceforge.net/projects/mingw/

Автор: niXman 12.04.11, 13:34
Цитата Алексей_Л @
качал это:
mingw-get-inst-20110316.exe

ну-ну :tong:

Автор: Алексей_Л 12.04.11, 13:44
Цитата niXman @
ну-ну

Это типа намёк на то, что это старьё?

Скачал твоё добро, тупо зареплейсил в папку CodeBlocks\MinGW
Собралось... заработало, урра!
*ушёл осваивать новый C++*

Пользуясь случаем немного поофтоплю:
Зачем в папке MinGW, той что создаёт сам C::B есть ещё одна вложенная папка mingw?
Например, в них обоих есть подпапка bin, и в обоих есть ar.exe и as.exe

Я реплейсил содержимое папки верхнего уровня.

Автор: niXman 12.04.11, 13:45
Цитата Алексей_Л @
намёк на то, что это старьё?

насколько я понял, там версия 4.5.2

Добавлено
Цитата Алексей_Л @
Зачем в папке MinGW, той что создаёт сам C::B есть ещё одна вложенная папка mingw?

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

Автор: Алексей_Л 12.04.11, 14:17
Так-с, опять на грабли...
Захотел пощупать std::thread.
Подключил:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <thread>

а оно ругается, мол не знаю я никакого thread'а.
причём в thread есть строки:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
     
    namespace std _GLIBCXX_VISIBILITY(default)

_GLIBCXX_HAS_GTHREADS не объявлен, его просто тупо задефайнить или есть более правильный способ устранить пробему?
Ой нет... нельзя просто так его дефайнить, куча ошибок лезеть внутри mutex'а.

Автор: niXman 12.04.11, 14:20
опцию "-std=c++0x" не забыли?

Автор: Алексей_Л 12.04.11, 14:44
нет, не забыл :(
P.S. Хотел предложить кидать сюда статьи по новому стандарту. (Попалась одна интересная статейка про потоки). И тут я прочитал подпись: niXman (try-catch) ;)
Спасибо за статью :thanks:

Автор: niXman 12.04.11, 14:49
по поводу std::thread - это системнозависимо. полагаю, что для того чтоб это работало в mingw, нужно что-то специфическое конфигурировать. или попытаться собрать используя pthread-win32. не знаю точно.. нужно пробовать..

Добавлено
хотя в линуксе это работает..

Автор: Алексей_Л 12.04.11, 15:33
Похоже странная солянка у меня получилась из MinGW с sourceforge и mingw от niXman.
Ибо у меня в папке lib есть libpthread.dll.a
Есть ещё флаг компилятору: -lpthread, так вот компиль на него не ругается, но и ошибки теже - не знает он про thread.

Автор: Повстанець 12.04.11, 16:00
std::thread под MinGW не работает. Не допилили ещё..

Добавлено
Могу скинуть допиленый, но не официальный. Работает только сам thread и mutex.

Автор: Алексей_Л 12.04.11, 16:14
Цитата Повстанець @
Могу скинуть допиленый, но не официальный.

валяй, побалуюсь, пока время есть
если на почту - то alekseyl <а> list <d> ru

Автор: Повстанець 12.04.11, 16:34
папку include записывать в gcc_path\lib\gcc\mingw32\номер_версии\
Исходники просто подключи к проекту.
Компилить с флагами
-D_POSIX_TIMEOUTS
-D_GLIBCXX__PTHREADS
-D_GLIBCXX_HAS_GTHREADS

thread.zip (, : 113)

Автор: Алексей_Л 12.04.11, 17:05
мдам-с, теперь он ругается на _GLIBCXX_BEGIN_NAMESPACE(std) в error_constants.h
и ещё куча связанных ошибок:
Скрытый текст

Цитата

d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\bits\error_constants.h|37|error: expected constructor, destructor, or type conversion before '(' token|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\bits\error_constants.h|123|error: '_GLIBCXX_END_NAMESPACE' does not name a type|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|61|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|61|error: template argument 1 is invalid|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|109|error: variable 'std::error_code std::make_error_code' has initializer but incomplete type|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|109|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|173|error: 'std::make_error_code' declared as an 'inline' variable|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|173|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|189|error: variable 'std::error_condition std::make_error_condition' has initializer but incomplete type|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|189|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|247|error: 'std::make_error_condition' declared as an 'inline' variable|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|247|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|308|error: expected class-name before '{' token|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error||In constructor 'std::system_error::system_error(std::error_code)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|314|error: class 'std::system_error' does not have any field named 'runtime_error'|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error||In constructor 'std::system_error::system_error(std::error_code, const string&)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|317|error: class 'std::system_error' does not have any field named 'runtime_error'|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error||In constructor 'std::system_error::system_error(int, const std::error_category&)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|331|error: class 'std::system_error' does not have any field named 'runtime_error'|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error||In constructor 'std::system_error::system_error(int, const std::error_category&, const string&)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\system_error|335|error: class 'std::system_error' does not have any field named 'runtime_error'|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex||In member function 'void std::unique_lock<_Mutex>::lock()':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|537|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|539|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex||In member function 'bool std::unique_lock<_Mutex>::try_lock()':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|551|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|553|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex||In member function 'bool std::unique_lock<_Mutex>::try_lock_until(const std::chrono::time_point<_Clock, _Duration>&)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|566|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|568|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex||In member function 'bool std::unique_lock<_Mutex>::try_lock_for(const std::chrono::duration<_Rep, _Period>&)':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|581|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|583|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex||In member function 'void std::unique_lock<_Mutex>::unlock()':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\mutex|595|error: 'errc' was not declared in this scope|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\thread||In member function 'std::size_t std::hash<std::thread::id>::operator()(const std::thread::id&) const':|
d:\program files\codeblocks\mingw\bin\..\lib\gcc\i686-pc-mingw32\4.6.0\..\..\..\..\include\c++\4.6.0\thread|241|error: 'std::_Fnv_hash' has not been declared|
||=== Build finished: 27 errors, 0 warnings ===|


*.cc правда в проект не подключал.
Но ошибка-то в объявлении
Edit: добавил, ошибок стало больше. но первые 27 - те же.

Автор: Алексей_Л 13.04.11, 08:17
Не работают alias'ы:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    using MyFloat = float;

Если их быть и не должно, то просьба подредактировать первый пост.

Кстати в шарпе со списками инициализации лучше сделано там можно инициализировать по именам:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        class Program
        {
            static void Main(string[] args)
            {
                CTest Test = new CTest{C = '0'};
            }
        }
     
        class CTest
        {
            public int A;
            public char C;
        }

Но тут вспоминается, что public - это зло...
Дело в том, что в шарпе есть свойства.
Отсюда вопрос: а есть/будут ли они и в новом C++?

Автор: Flex Ferrum 13.04.11, 08:20
Цитата Алексей_Л @
Отсюда вопрос: а есть/будут ли они и в новом C++?

Нет.

Добавлено
Цитата Алексей_Л @
Не работают alias'ы:

Так их поддержка в gcc пока и не заявлена.

Автор: niXman 13.04.11, 17:29
Цитата Повстанець @
папку include записывать в gcc_path\lib\gcc\mingw32\номер_версии\
Исходники просто подключи к проекту.
Компилить с флагами
-D_POSIX_TIMEOUTS
-D_GLIBCXX__PTHREADS
-D_GLIBCXX_HAS_GTHREADS

походу, взято отсюда: http://lists-archives.org/mingw-users/18686-pthreads-recipe-for-using-std-thread-with-mingw-mingw32-mingw-w64.html

но это изврат, IMHO.

полазав по хидерам mingw обнаружил, что для WIN32 есть реализация, но она что-то не работает. нужно всерьез заняться изучением этого момента, но пока некогда.

с другой стороны, можно и не использовать WIN32 реализацию, а использовать имеющуюся и рабочую реализацию для POSIX. в этом случае, нужно понять что сделать, чтоб использовать pthreads-win32.

Добавлено
касательно thread-библиотеки, можно почитать тут: http://www.mail-archive.com/mingw-w64-public@lists.sourceforge.net/msg01433.html

как оказалось, в исходниках gcc, имеются реализации thread-библиотеки для следующих ОС:
Цитата
gthr-aix.h
gthr-dce.h
gthr-gnat.c
gthr-gnat.h
gthr-lynx.h
gthr-mipssde.h
gthr-nks.h
gthr-posix95.h
gthr-posix.c
gthr-posix.h
gthr-rtems.h
gthr-single.h
gthr-solaris.h
gthr-tpf.h
gthr-vxworks.h
gthr-win32.h

как видно, есть и реализация для win32. но странно то, что в моей сборке этого файла нет. наверняка нужно копаться в опциях configure....

Автор: ёже 21.04.11, 06:43
C++0x это новый вариант? Чет я слышал что страуструп и ко вроде только недавно приступили к переделке...
Хмм... то есть это вариант с++ 2010 года?

Автор: D_KEY 22.04.11, 07:49
ёже, en.wikipedia: C++0x

Автор: niXman 03.05.11, 22:48
оказывается Strongly Typed Enums уже реализовали!
оно даже работает! 8-)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    enum: char { e1 };
    enum: short { e2 };
    enum: int { e3 };
    enum: long long { e4 };
     
    int main() {
       std::cout << sizeof(e1) << std::endl;
       std::cout << sizeof(e2) << std::endl;
       std::cout << sizeof(e3) << std::endl;
       std::cout << sizeof(e4) << std::endl;
    }

http://liveworkspace.org/code/0f385b6f43d17669840d84b31c5c133c
дока: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf

Автор: Алексей_Л 23.05.11, 11:16
А кто-нибудь знает:
Будет ли полная поддержка C++0x в MSVS2010? Обновка выйдет к нему или скоро уже новая версия будет?

Автор: niXman 18.06.11, 19:36
кому интересно: удалось собрать mingw на базе gcc-4.7.0-snapshot c поддержкой потоков и всего что с ними связанно.
так же, включает поддержку искаропки Graphite+LTO+OpenMP. и на сколько я смог проверить, даже все работает.
тестируем: i686-pc-mingw32-bin-4.7.0-snapshop-20110617-rev-0

Добавлено
оценить LTO можно по примеру: http://kemiisto.blogspot.com/2010/09/lto.html
OpenMP: http://people.sc.fsu.edu/~jburkardt/c_src/open_mp/open_mp.html

Автор: Alexander N 21.06.11, 13:53
А начиная с какого стандарта Boost включена в стандарт С++?

Автор: Алексей_Л 21.06.11, 14:24
Цитата Alexander N @
Boost включена в стандарт С++

не включен он в C++, просто из него кое что позаимствовали, те же thread, например.

P.S. Хочу C++1x в MSVS...

Автор: MyNameIsIgor 13.08.11, 09:30
Дождались :yes:

Автор: niXman 13.08.11, 09:33
ура :rolleyes:

Автор: Adil 13.08.11, 11:51
:good:

Автор: Qraizer 13.08.11, 12:01
:dance: :dance: :dance: :yummy:
:writer: :writer: :wizard: :writer: :rake: :rtfm: :wacko: :slow: :fool:
:rtfm: :writer: :rtfm: :writer: :victory:
Чего и вам желаю.

Автор: Alexander N 13.08.11, 12:05
:dance: :dance: :dance: :music: :popcorn:

Автор: maxim84_ 13.08.11, 16:23
Здорово! :good:

Автор: Flex Ferrum 15.08.11, 09:19
Фуф! Дождались! :good:

Автор: prografix 17.08.11, 10:14
Кто-нибудь может по-русски объяснить, что есть полезного в новом стандарте?
Желательно несколько примеров без использования STL.

Автор: niXman 17.08.11, 10:15
Цитата prografix @
без использования STL

вы разделом ошиблись. пхп тут: PHP :D

Автор: Повстанець 17.08.11, 10:20
Цитата prografix @
Кто-нибудь может по-русски объяснить, что есть полезного в новом стандарте?
Более актуальній вопрос -- что в новом стандарте безполезно. :D

Автор: Flex Ferrum 17.08.11, 10:41
Цитата prografix @
Кто-нибудь может по-русски объяснить, что есть полезного в новом стандарте?

См. первый пост темы. :)

Автор: Pacific 17.08.11, 11:01
Цитата Flex Ferrum @
Цитата prografix @
Кто-нибудь может по-русски объяснить, что есть полезного в новом стандарте?

См. первый пост темы. :)

Вот только подредактировать бы его, в соответствии с принятым стандартном. А то в том посте еще даже про концепты текст не удалили.

Автор: MyNameIsIgor 17.08.11, 19:15
Цитата Pacific @
А то в том посте еще даже про концепты текст не удалили.

IMHO, и слава Богу! Чтобы потомки не забывали благие намерения.
Первый пост не надо редактировать, он отлично написан, за что вечный респект archimed7592.
Скрытый текст
Кстати, а где он? :ph34r:

Автор: Qraizer 17.08.11, 20:40
Концепты оказались очень серьёзной для реализации фичей. Их не удалили, а отложили до более спокойных времён.

Автор: prografix 18.08.11, 08:06
Получается, что и сказать нечего, а так радовались.
Ладно, буду и дальше пользоваться старым С++.

Автор: Повстанець 18.08.11, 08:14
Цитата prografix @
Получается, что и сказать нечего, а так радовались.
Ладно, буду и дальше пользоваться старым С++.
42я страница. Флуда почти нет, уверен и этот скоро снесут. Открывай с первой и читай. Мало -- открывай последний доступный черновик, читай там.

Автор: Radagast 19.08.11, 15:53
печально то, что concept gcc вроде как забросили, а др подвижек в этом направлении не видно :(

Автор: Flex Ferrum 20.08.11, 07:08
А всё-таки, что ни говори, а новые фишки стандарта упрощают код и разработку.

Автор: niXman 20.08.11, 07:10
Цитата Flex Ferrum @
А всё-таки, что ни говори

как-то не уверенно звучит ;)

Автор: Flex Ferrum 20.08.11, 07:12
Цитата niXman @
как-то не уверенно звучит ;)

Ну, в интернете (например, на том же хабре) можно встретить много критики в адрес нового стандарта. Но, как говориться, критикуй, не критикуй, а код выглядит таки проще.

Автор: niXman 20.08.11, 07:14
Цитата Flex Ferrum @
много критики в адрес нового стандарта.

а критики в адрес прошлого стандарта меньше? ;)
или вообще критики с++ ;)

Автор: Flex Ferrum 20.08.11, 07:17
Цитата niXman @
а критики в адрес прошлого стандарта меньше? ;)
или вообще критики с++ ;)

:D

Автор: niXman 20.08.11, 07:18
Цитата Qraizer @
отложили до более спокойных времён.

поясни.

Добавлено
до каких таких спокойных?
и что специфичного в концептах?

Автор: Flex Ferrum 20.08.11, 07:26
Для примера.
Было:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    xstl::Collection<IUnitRace*> races = LocalGameServer::GetGameStartingOptions()->Races();
    m_StoredWizards = *LocalGameServer::GetGameStartingOptions()->StoredWizards;
     
    xstl::Collection<IUnitRace*>::const_iterator p = races.cbegin(), e = races.cend();
     
    for (; p != e; ++ p)
        ui.m_StartRace->addItem(QString::fromStdString((*p)->RaceName()));


Стало:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto const& races = m_StartingOptions->Races();
    m_StoredWizards = *LocalGameServer::GetGameStartingOptions()->StoredWizards;
     
    BOOST_AUTO_FOREACH(race, races)
        ui.m_StartRace->addItem(QString::fromStdString(race->RaceName()));


BOOST_AUTO_FOREACH - это от "хорошей" жизни на VS 2010. В gcc это был бы range-for-loop.

Автор: niXman 20.08.11, 07:37
Flex Ferrum, что правда, что микрософт не собирается реализовывать стандарт полностью? или они только отложили реализацию?

Автор: Flex Ferrum 20.08.11, 07:52
Цитата niXman @
Flex Ferrum, что правда, что микрософт не собирается реализовывать стандарт полностью? или они только отложили реализацию?

Ну, я так понимаю, работу над компилем из VS 2010 (основным) они закончили году в 2009-ом. Дальше был только багфикс. По этому из нового стандарта туда попало немного... Ждём 2012-ыйvNext. :)

Автор: niXman 20.08.11, 08:01
Цитата Flex Ferrum @
Ждём 2012-ый.

все таки надежда есть..

Автор: Qraizer 20.08.11, 10:30
niXman, концепты были призваны в явном виде описывать контракты. Очень восстребовано при статическом полиморфизме и вообще при жёстком обобщённом программировании, где шаблон на шаблоне и шаблоном погоняет. Сейчас контракты описываются либо в документации, либо никак. Концепты могли, во-первых, рассказать программисту об этих контрактах без необходимости лазать в мануалы, и во-вторых, предоставить компилятору информацию об этих контрактах. Последнее наиболее значимо, ибо он в результате становился способным выдавать диагностику на ранних стадиях второго этапа компиляции шаблона в точке инстанцирования. Если сейчас не редкость увидеть километровую диагностику со ссылкой куда-то вглубь приватных частей реализации шаблона, то при концептах компилер просто заранее бы, ещё до инстанцирования, их проверил и сразу б выдал ошибку со ссылкой на нарушаемый аргументами контракт.
Однако контракты могут разными. Попытки даже описать концепты для всякоразных мыслимых видов контрактов и реализовать их хоть в каком-то виде показали, что если иметь возможность любые мыслимые контракты описывать концептами, то они будут требовать от реализаций по сути поддержки парадигмы декларативного программирования. Это иначе чем революцией назвать сложно. Поддержка функциональной парадигмы семечки по сравнению с концептами. В общем, комитет решил удалить концепты из текущего рассматриваемого драфта и вернуться к ним позже. Иначе C++1x рисковал либо выйти сильно после конца света, либо с концептами только на бумаге, как по сути случилось с экспортом шаблонов.

Автор: niXman 20.08.11, 10:32
Qraizer, понял. спасибо.

Автор: niXman 04.10.11, 22:39
в течении прошлой недели были реализованы две новые возможности:
1. explicit override control.
2. non-static data member initializers.

завтра соберу версию из trunk`а.

Автор: niXman 05.10.11, 15:05
залил :)

Автор: Flex Ferrum 07.10.11, 19:43
А Microsoft Visual Studio пока в позиции догоняющего. В MS Visual Studio 11 (Developers Preview), которое предлагается скачать, нововведений в плюсах - кот наплакал:

Цитата

Standard Template Library

As part of the added support in Visual Studio 11 Developer Preview for the C++11 specification, the Standard Template Library (STL) support in Visual Studio is extended to provide the additional programming constructs that specification requires. Highlights include the following:

Support for new headers <atomic>, <chrono>, <condition_variable>, <filesystem>, <future>, <mutex>, <ratio>, and <thread>.

To optimize memory resource usage, all containers are now smaller given their current representations. For example, in x86 release mode with default settings, std::vector has shrunk from 16 bytes in Visual C++ 2010 to 12 bytes in Visual C++ in Visual Studio 11 Developer Preview, and std::map has shrunk from 16 bytes in Visual C++ 2010 to 8 bytes in Visual C++ in Visual Studio 11 Developer Preview.

Other C++11 Enhancements

SCARY iterators: As permitted but not required by the C++11 Standard, SCARY iterators have been implemented. For more information, see the PDF document SCARY Iterator Assignment and Initialization.

Stateless lambdas, which is code beginning with an empty lambda-introducer [] and capturing no local variables, are now implicitly convertible to function pointers as required by the C++11 Standard.

Scoped enumerations support. The C++ enum class enum-key is now supported.


Единственно вкусным из всего этого можно считать поддержку потоков "из коробки" и по стандарту. Остальное всё - фигня, я бы сказал.

Ссылки:
http://msdn.microsoft.com/en-us/library/hh...=VS.110%29.aspx
http://blogs.msdn.com/b/vcblog/archive/201...2/10209291.aspx
По последней ссылке камменты просто жгут. Авторы посылают массу лучей "любви" в адрес команды разработчиков VC++. И в массовом порядке мигрируют на gcc. :D

Цитата
I wonder if the votes here http://visualstudio.uservoice.com/forums/1...tegory/30937-c- about C++11 got ignored.

As I understand there's the IDE team, the libraries team, the compiler team, etc. From VS2008 to VS2010 quite a few C++11 features were added. VS2010 was released on April 12 2010. Can someone tell me what the compiler team has been doing for 17 months???

+100500. Правильно, а зачем? Что именно хотят пользователи - им расскажут маркетологи. А хотят они, как выясняется, совсем другого:

Цитата
Diegum
12 Sep 2011 2:48 PM
#
Thank you guys for the feedback (still ongoing, as I assume there are some of you who hasn't yet read this Stephan's article at the time I'm writing this and will also manifest your feelings when you read it.)

If we compare the VC++ compiler against competitors, in particular in the C++11 compliance row we are behind. So the question is "why isn't MS investing in leading the standard compliance race as it was by the time Visual C++ 2010 was released?"

A careless answer would state "because MS just doesn't care." There's another reality that I invite you guys to observe together. As we've admitted these last months (in this blog, at Channel 9 with my colleague and friend Charles Torre, etc.) native development in general and C++ in particular got a lower priority amongst the many languages that Visual Studio features. Not to justify my employer here, but it should be accepted that it was an industry trend that school of thinking that "modern languages" were managed ones, while native languages were expected to become legacy for mainstream development over the time. There's a great keynote delivered by our C++ Principal Architect Herb Sutter about the resurgence of C++ in the firmament – what can’t be understood as a near death of managed languages, just as the result of recent years innovation trends in the IT industry that made C++ re-invited to the dialog table.

Много буков про желания пользователей в отношении VC++11
In particular at Microsoft, we called this resurgence as C++ Renaissance and its first evidences were seen in the last release of Visual C++ (2010) with the implementation of the by-then latest draft of C++0x as no other compiler featured, a brand new library for parallel computing whose design followed some STL philosophy among other features intending to start adding value again and not just being an “also included” tool inside Visual Studio. A later feature pack brought some architecture features like dependency graphs or layer validation.

It was evident, though, that catching up after the end of that “managed for all” school of thinking was to take time, and in fact some of our moves implied to set back certain features in order to re-architect those in moving forward (I guess you are thinking now about the cut C++/CLI IntelliSense, which we finally closed the gap and it’s coming back in the next version).

But there were still more areas where we needed to shorten that distance. ALM for instance: many of you complained that Visual Studio offered several ALM features, only when talking about .NET development. Well, not for much longer: we announced last May our plans to bring ALM capabilities to C++ as well.

There were more, though: productivity features in the IDE. How could it happen that something so well-established in the .NET worlds like Code Snippets were never available in C++? That was what many of you guys asked us as well. We recently posted a couple of articles telling what to expect in the next version of the IDE. And it’s certainly not just about Code Snippets in C++.

MS Technical Fellow Mohsen Agsen said in an interview at the beginning of the year that “it won’t sound crazy if some upcoming features arrive primarily and first for C++ and then eventually for other Visual Studio languages.” Last June we announced a new technology (which we submitted as a standard, becoming just one of its implementers): C++ AMP for heterogeneous parallelism in CPUs, GPUs and other cores.

In this struggle to put C++ back at the main scene, we must decide and allocate resources wisely in order to get some progress in ALM, developer productivity –including performance-, C++11 standard compliance, parallelism, and many other aspects related with your ultimate goal, that is shipping software. As a consequence of that, it’s unavoidable that we’ll resign some particular aspect at the sake of the overall development experience, as it’s being in this case, featuring as many C++11 elements at the level other competitors do.

There are more news for C++ developers and in that sense I invite you to watch the keynotes at the BUILD Windows conference tomorrow (they’ll be broadcasted live). There are going to be sessions about C++ development that won’t be broadcasted live, but will be available 24 hours after being performed. Some of you criticized us for repeating too much “we aren’t telling about that point at this time.” Well, this week we’ll finally talk. That’s a relief for all of us who were listening you but couldn’t talk in observance of company policies.


Mine was a long speech that doesn’t address your reasonable claims for variadic templates or other C++11 aspects but fights that perception that “MS doesn’t care.” We do care about all these issues, we are catching up in a way that maximizes several influential aspects of the development experience.

По русски выделенное звучит совсем нецензурно... :wall:

Добавлено
Такой вот он, ренессанс C++ по microsoft'овски...

Автор: niXman 08.10.11, 04:21
со студией вроде как идут исходники стандартной библиотеки? если да - выложите кто-то плиз на файлообменник. любопытно поковырять.
премного благодарен.

Автор: phprus 08.10.11, 07:14
niXman
Да, есть такое: http://narod.ru/disk/27675792001/MSVC2010.7z.html (из MSVC 2010).

Интересно, а для VC++ вообще существует стандартная библиотека, приближенная по функциональности к C++11, хотя-бы в рамках поддерживаемых компилятором возможностей или приближенная к libstdc++ по оптимизированности(про оптимизированность мое сугубо личное и субъективное мнение).

Автор: niXman 08.10.11, 07:16
phprus, спасибо. а случаем от 2011 не завалялась?

Добавлено
насколько мне известно, микрософт юзает Dinkumware STL.

Автор: phprus 08.10.11, 07:23
Цитата niXman @
phprus, спасибо. а случаем от 2011 не завалялась?

Нет, этого зверька я еще не устанавливал и не смотрел.

Да и Windows 2003 Server оно похоже не поддерживает, что для меня очень печально.

Автор: niXman 08.10.11, 21:50
разве никто не устанавливал 2011 студию?

Автор: amdei 08.10.11, 23:24
Цитата niXman @
насколько мне известно, микрософт юзает Dinkumware STL.

Dinkumware совершенно точно был в каком-то из C++ Builder'ов.
И там STL совершенно точно иной чем в MS.

Помню точно, ибо огребли мы с этим проблем по самые уши...

Добавлено
О! Копирайт в хедерах 2010-й:

/* Copyright © 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.20:0009 */

Автор: niXman 08.10.11, 23:36
Цитата amdei @
Dinkumware совершенно точно был в каком-то из C++ Builder'ов

вряд ли. билдер никогда не поддерживал стандарт, тем более, что он к этому не стремился. а Dinkumware производит самый строго соответствующий стандарту компилятор. противоречий не находите ;)

Автор: amdei 08.10.11, 23:46
Цитата niXman @
Цитата amdei @
Dinkumware совершенно точно был в каком-то из C++ Builder'ов

вряд ли.

Хош верь, а хош - проверь.
Дело как говориться хозяйское

http://www.google.ru/search?q=Dinkumware+C%2B%2B+Builder

Автор: trainer 09.10.11, 05:23
Цитата amdei @
Dinkumware совершенно точно был в каком-то из C++ Builder'ов.
В Builder'е сначала был RogueWave, потом заменили на Dinkumware. В MSVC - Dinkumware.

Добавлено
Цитата amdei @
О! Копирайт в хедерах 2010-й:

/* Copyright © 1992-2009 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
V5.20:0009 */
Это и есть Dinkumware.

Добавлено
http://www.plauger.com/index.html :
Цитата
P.J. Plauger is President of Dinkumware, Ltd.

Автор: amk 09.10.11, 08:18
Старые билдеры пользовались библиотекой от RogueWave. Последние - не знаю

Автор: aster_x 14.10.11, 11:31
Ребята уже час гугглю. Где можно скачать стандарт С++11. Одним файлом? Если такой есть :)

Добавлено
Или он просто идет как расширение к "старому" стандарту.

Автор: MyNameIsIgor 14.10.11, 12:02
aster_x, смотреть надо здесь :)

Автор: aster_x 14.10.11, 13:06
ТАк там все "разюросанно".

Я думал что есть гдето файлик pdf :)

Автор: MyNameIsIgor 14.10.11, 13:16
aster_x, с вами дело плохо.

Автор: aster_x 14.10.11, 13:25
MyNameIsIgor Спасибо! Вам большое! Действительно! Нужны быть более внимательным :)

Автор: aster_x 14.10.11, 17:44
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        if(ii >5 and ii< 67)
        <%
            ii =6 ,ii++, ii++, ii+=2;
            cout<<ii<<endl;
        %>


Новый стандарт, не имоверно удобно(за исключением логических скобок)...
Мне стыдно что я его раньше не видел. :blush:

Автор: Алексей_Л 14.10.11, 18:36
Цитата aster_x @
Новый стандарт, не имоверно удобно(за исключением лошических скобок)...
Мне стыдно что я его раньше не видел.

шшш-то это?
1. <% и %>
2. что за извращение с ii на 3ей строке?

Автор: Flex Ferrum 14.10.11, 18:40
Цитата Алексей_Л @
<% и %>

Это - диграфы.

Автор: amdei 14.10.11, 18:41
1. [lex.digraph] - см. стандарт. Можешь еще [lex.trigraph] посмотреть, чтоб спалося сегодня крепче. :)
2. А шо? Ну пемеренная меняется, ну и шо...

Автор: amk 14.10.11, 18:45
aster_x, ничего нового в этом примере нет, все в рамках стандарта C (не ++) образца 1989 года

<% это диграф для {
%> это диграф для }

ii =6 ,ii++, ii++, ii+=2; это такой извращенный способ присвоения переменной ii значения 10, когда переменной присваивается значение 6, потом она два раза инкрементируется, и в конце увеличивается еще на 2.

aster_x, Алексей_Л стыдно не знать основ языка, которым пользуетесь.

Автор: Алексей_Л 14.10.11, 19:08
Цитата amk @
стыдно не знать основ языка

не спорю, стыдно, вот напишет Бьерн Страуструп новую книжку, с учётом нового стандарта - куплю и подтяну теорию.
Цитата amk @
<% это диграф для {
%> это диграф для }

не знал, спасибо всем , кто разъяснил
Цитата amk @
ii =6 ,ii++, ii++, ii+=2; это такой извращенный способ присвоения переменной ii значения 10

да это-то понятно :), просто тема вроде новому стандарту посвящена, отсюда и вопрос появился - в чём смысл такого... такого.

Автор: aster_x 14.10.11, 19:11
Цитата amk @
стыдно не знать основ языка, которым пользуетесь.

Согласен. Но я поменяюсь обещаю. :oops:

Автор: amk 14.10.11, 20:07
Я это к тому, что все что ты там написал, не в новом стандарте появилось, а чуть ли не с самого появления языка (еще С) там было. Просто не везде есть фигурные скобки, да и другие символы. для этого и введены были диграфы и триграфы, чтобы и там можно было вводить программу.

Автор: aster_x 14.10.11, 20:51
amk Блин! Я считал что "Лафоре" знает все. И ничего лишнего. :wall:

Теперь сижу стандарт зубрю. :blush:

Автор: amk 15.10.11, 04:33
aster_x, про эти диграфы и триграфы надо знать, но помнить их незачем и тем более нет смысла их втыкать в свою программу. Честно говоря я уже давно не сталкивался с оборудованием, не поддерживающим весь нужный набор символов.

Автор: Adil 15.10.11, 05:21
Не, такое оборудование довольно часто встречаю, но вот набирать на нём исходник... даже и мысли такой не было. :)

Автор: amk 15.10.11, 06:03
Я про то, которое именно для набора текста было предназначено. Даже на терминалах бывало не было тех же фигурных скобок. не уверен, что они вообще в той кодировке были.

Автор: D_KEY 27.01.12, 09:28
У меня глупый вопрос. Будет ли вызван деструктор:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class SomeType  {
        int number;
     
    public:
        SomeType(int new_number) : number(new_number) {}
        SomeType() : SomeType(42) { throw "aaa"; }
        ~SomeType() { std::cout << "~SomeType()" << std::endl; }
    };
     
    // ...
     
    {
        SomeType x;
    }

Автор: Бобёр 27.01.12, 10:23
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeType() : SomeType(42) { throw "aaa"; }

Так писать нельзя. SomeType в данном случае не базовый тип и не член.

Автор: D_KEY 27.01.12, 10:34
Цитата Бобёр @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    SomeType() : SomeType(42) { throw "aaa"; }

Так писать нельзя. SomeType в данном случае не базовый тип и не член.

Бобер, тема о новом стандарте, если ты не заметил.

Цитата 12.6.2/6
A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-
decltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class,
it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected
by the mem-initializer is the target constructor. The principal constructor is the first constructor invoked
in the construction of an object (that is, not a target constructor for that object’s construction). The
target constructor is selected by overload resolution. Once the target constructor returns, the body of the
delegating constructor is executed. If a constructor delegates to itself directly or indirectly, the program is
ill-formed; no diagnostic is required. [ Example:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct C {
      C( int ) { }                // #1: non-delegating constructor
      C(): C(42) { }              // #2: delegates to #1
      C( char c ) : C(42.0) { }   // #3: ill-formed due to recursion with #4
      C( double d ) : C(’a’) { }  // #4: ill-formed due to recursion with #3
    };

— end example ]


Добавлено
Да, будет:
Цитата 15.2/2
An object of any storage duration whose initialization or destruction is terminated by an exception will
have destructors executed for all of its fully constructed subobjects (excluding the variant members of a
union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution
and the destructor has not yet begun execution. Similarly, if the non-delegating constructor for an object
has completed execution and a delegating constructor for that object exits with an exception, the object’s
destructor will be invoked.
If the object was allocated in a new-expression, the matching deallocation
function (3.7.4.2, 5.3.4, 12.5), if any, is called to free the storage occupied by the object.

Автор: Бобёр 27.01.12, 11:48
Ой, .. да, в Новом Стандарте так, оказывается, будет можно, я пропустил этот момент, спасибо. :whistle:
Этой штуки давно не хватало, кстати :yes:

Автор: D_KEY 27.01.12, 11:50
Цитата Бобёр @
Этой штуки давно не хватало, кстати :yes:

Но ситуация с исключением и вызовом деструктора не столь гладкая, ибо добавилось обстоятельство, при котором в случае исключения в конструкторе объекта вызывается его же деструктор. Раньше такого не могло быть в принципе...

Автор: niXman 27.01.12, 12:21
Цитата D_KEY @
Будет ли вызван деструктор:

наверное есть какой-то принцип не позволяющий скачать компилятор?

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    class SomeType  {
        int number;
     
    public:
        SomeType(int new_number) : number(new_number) {}
        SomeType() : SomeType(42) { throw "aaa"; }
        ~SomeType() { std::cout << "~SomeType()" << std::endl; }
    };
     
    int main() {
       try {
          SomeType st;
       } catch ( ... ) {
          std::cout << "catching exception" << std::endl;
       }
    }

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    C:\test>g++ -std=c++0x delegat.cpp -odelegat
     
    C:\test>delegat
    ~SomeType()
    catching exception
     
    C:\test>

Автор: D_KEY 27.01.12, 12:30
Цитата niXman @
наверное есть какой-то принцип не позволяющий скачать компилятор?

Сейчас еще не наступила та стадия поддержки стандарта, чтобы проверять подобные вещи компиляторами :)

Автор: niXman 27.01.12, 12:57
Цитата D_KEY @
еще не наступила та стадия поддержки стандарта, чтобы проверять подобные вещи компиляторами

тебе походу виднее, не то что разработчикам.

Добавлено
скажи, как определил что в данном случае стадия не та?

Добавлено
не придирка. просто любопытно, чем ты руководствуешься.

Автор: D_KEY 27.01.12, 13:07
Цитата niXman @
тебе походу виднее, не то что разработчикам.

:wacko:
Виднее Стандарту. Я не имел возможности искать этот момент там, потому и спросил - вдруг кто уже этот момент для себя прояснил. Как добрался до стандарта - нашел.

Цитата
скажи, как определил что в данном случае стадия не та?

(1) Стандарт поддерживается не полностью, (2) есть известные баги компилятора при работе с фичами нового стандарта.

Автор: niXman 27.01.12, 13:11
изначально был просто вопрос, без заднего смысла. но судя по ответам, ты посчитал эти вопросы придирками.
забудь...

Автор: D_KEY 27.01.12, 13:13
Цитата niXman @
но судя по ответам, ты посчитал эти вопросы придирками.
забудь...

Да вроде нет - ответил же :)

Автор: niXman 27.01.12, 13:17
D_KEY, если кратко - можно просто посмотреть набор тестов для delegating constructors. и основываясь на выводах сделанных из тестов, можно понять больше чем тебе ответят на форуме.

Автор: Radagast 27.01.12, 13:23
вопрос теперь в том, как в деструкторе отличить, какие конструкторы успели отработать :(

Автор: D_KEY 27.01.12, 13:24
Цитата niXman @
D_KEY, если кратко - можно просто посмотреть набор тестов для delegating constructors. и основываясь на выводах сделанных из тестов, можно понять больше чем тебе ответят на форуме.

Как думаешь, если у меня не нашлось времени, чтобы полистать стандарт, нашлось бы оно для поиска и просмотра тестов?
А от стандарта толку явно больше.

Добавлено
Цитата Radagast @
вопрос теперь в том, как в деструкторе отличить, какие конструкторы успели отработать :(

Вот и я теперь думаю...
Собственно, вопрос вырос из холивара, где мне припомнили, что я ругал Delphi за вызов деструктора в случае исключения в конструкторе(у них так происходит всегда) :D

Но думаю, что на практике, все будет более-менее нормально.

Автор: Qraizer 27.01.12, 13:28
Radagast, а зачем?

Автор: D_KEY 27.01.12, 13:34
Цитата Qraizer @
Radagast, а зачем?

Ну в общем случае, тебе может быть нужно что-то отдать/удалить/отписаться/"отрегистрироваться" и т.д. и т.п. только в том случае, если выполнился делегирующий конструктор. Понятно, что дизайн в этом случае, скорее всего, кривой, но тем не менее...

Добавлено
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    class A
    {
    public:
        A()
            : A(10)
        {
            // тут код с возможным исключением
            // регистрируемся где-нибудь
        }
     
        ~A()
        {
            // тут нужно узнать, регистрировались ли мы :(
        }
     
    private:
        A(int a);
     
        int ma;
    };

Автор: Повстанець 27.01.12, 14:16
Цитата niXman @
C:\test>g++ -std=c++0x delegat.cpp -odelegat

C:\test>delegat
~SomeType()
catching exception

C:\test>
Уххх. Аццкая фича какая то. :wacko: Надеюсь хоть без делигирующих конструкторов всё будет по старому.

Автор: D_KEY 27.01.12, 14:19
Цитата Повстанець @
Надеюсь хоть без делигирующих конструкторов всё будет по старому.

Конечно.
Собственно, делигирующие конструкторы - это уже и не конструкторы получаются, а специальная над ними надстройка... Может стоило синтаксис даже новый ввести...

Автор: Qraizer 27.01.12, 21:48
Я думаю, это естественно. Конструкторы находятся в весьма особом положении по сравнению с другими методами. Все остальные методы имеют право опираться на инварианты класса, тогда как конструкторы такого права не имеют, они эти инварианты создают. Если декомпозиция приводит в выделению общих конструирующий действий в отдельные методы, такие методы становятся тоже специальными, что добавляет путаницы, особенно вкупе с полиморфизмом. Вот и нечего. Теперь в роли таких методов будут делегирующие конструкторы.

Автор: amk 28.01.12, 03:36
Цитата Radagast @
вопрос теперь в том, как в деструкторе отличить, какие конструкторы успели отработат

А в чем проблема? Конструктор ссылающийся на другой конструктор, сам созданием инвариантов уже не занимается. К моменту начала выполнения его тела объект уже создан, и он отрабатывается как обычный метод. Если исключение выбросится из конструктора, что в списке инициализации (делегируемого), объект незавершен - деструктор не вызывается. Если исключение выбросится в теле такого делегирующего конструктора, то как и в обычном методе разматывается стек и вызывается деструктор.

Добавлено
Даже поведение компилятора менять не надо

Автор: D_KEY 28.01.12, 08:24
Менять, конечно же, не надо. Все так и должно быть. Вопрос только в том, насколько это будет путать начинающих. Казалось бы, фишка как раз для упрощения, а выходит даже наоборот...

Автор: Qraizer 28.01.12, 12:38
Разве наоборот? Один конструктор же уже отработал, инварианты в порядке, почему деструктор не должен быть вызван? Некий код, делающий дополнительно ещё что-то, не должен нарушать инварианты, а если же и нарушает временно, так ситуация ничем не отличается от других методов.

Автор: D_KEY 28.01.12, 12:42
Цитата Qraizer @
почему деструктор не должен быть вызван?

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

Автор: Qraizer 28.01.12, 21:21
Хм... ну как сказать... Инварианты инвариантами, но ведь помимо создания инвариантов и определённости состояния на конструкторы возлагается также конкретность этой определённости. Иначе зачем их перегружать? Сконструировали, затем проинициализировали. Получится Дельфи. Т.к. эффективнее сконструировать сразу в нужном состоянии, нежели сначала в дефолтовом, а только затем перевести в нужное, то перегрузка конструкторов оправдана. Тут то же самое. Уже есть конструктор, который создаёт инвариант, остаётся только дозадать состояние экземпляра.
Формально да, есть определённый диссонанс. Думаю, со временем придём к выводу, что делегируемые конструкторы обычно не должны быть публичными.

Автор: D_KEY 03.02.12, 10:37
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto x = { 1, 2, 3, 4, 5 }; // ok a has type std::initializer_list<int>


Должен ли выводится тип для std::initializer_list<std::initializer_list<int>>:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto x = { {1, 2}, {3, 4, 5} };

?

Автор: Flex Ferrum 03.02.12, 10:39
Цитата D_KEY @
Должен ли выводится тип для std::initializer_list<std::initializer_list<int>>:

Вроде как нет.

Автор: niXman 03.02.12, 10:40
по опыту - нет.
по стандарту - хз.

Автор: D_KEY 03.02.12, 10:44
gcc не выводит, хотелось бы узнать, как по стандарту. А то я сам не могу понять должен или нет :wacko:
Вообще было бы логичным, чтобы выводил...

Добавлено
Обидно, если нельзя, потому как даже "руками" не сделать:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::initializer_list<auto> x = { {1, 2, 3}, {4, 5, 6} }; // так нельзя

Автор: Qraizer 03.02.12, 12:22
Думаю, нет.
Цитата 7.1.6.4 auto specifier
6 ... Obtain P from T by replacing the occurrences of auto with either a new invented type template parameter U or, if the initializer is a braced-init-list (8.5.4), with std::initializer_list<U>. The type deduced for the variable d is then the deduced type determined using the rules of template argument deduction from a function call (14.9.2.1), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed. ...

Цитата 14.9.2.1 Deducing template arguments from a function call
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. If removing references and cv-qualifiers from P gives std::initializer_list<P'> for some P' and the argument is an initializer list (8.5.4), then deduction is performed instead for each element of the initializer list, taking P' as a function template parameter type and the initializer element as its argument. Otherwise, an initializer list argument causes the parameter to be considered a non-deduced context (14.9.2.5).
Внутренний std::initializer_list<> - это невыводимый контекст.

P.S. Это не последний драфт, последний сейчас вне доступа.

Автор: D_KEY 03.02.12, 12:27
Да, судя по всему так... Спасибо.
Печально.

Автор: Qraizer 03.02.12, 12:33
И то верно. А какой тип должен быть выведен для x? std::initializer_list<int>[2] или int[3][2]?

Автор: D_KEY 03.02.12, 12:34
Цитата Qraizer @
А какой тип должен быть выведен для x? std::initializer_list<int>[2] или int[3][2]?

Почему тебя не смущает, что для
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto x = { 1, 2, 3 };

Он выводит не массив, а std::initializer_list<int>?
И почему в случае вложенности он не может сделать тоже самое?

Автор: Qraizer 03.02.12, 12:36
Там ещё пример есть:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class T> void g(T);
     
    g({1,2,3}); // error: no argument deduced for T
Толи g<int[]>, толи g<std::initializer_list<int>>

Автор: D_KEY 03.02.12, 12:38
Ну и да:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        auto x = {1, 2, 3};
        auto y = {1, 2, 3};
        auto z = {x, y}; // ok


<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        auto z = { {1, 2, 3}, {1, 2, 3} }; // не осилил

:(

Автор: Qraizer 03.02.12, 12:38
Цитата D_KEY @
Он выводит не массив, а std::initializer_list<int>?
Потому что для этих случаев есть отдельные пункты, а для остальных "the deduced type determined using the rules of template argument deduction from a function call"

Добавлено
Думаю, тут дело в неоднозначности намерений программиста. В случае простого auto = {...} всё просто - это braced-init-list, а в случае f({...}} будьте добры явно указать в прототипе f(), что хотите там видеть std::initializer_list<int>.

Автор: D_KEY 03.02.12, 12:45
Цитата Qraizer @
Думаю, тут дело в неоднозначности намерений программиста. В случае простого auto = {...} всё просто - это braced-init-list, а в случае f({...}} будьте добры явно указать в прототипе f(), что хотите там видеть std::initializer_list<int>.

Это понятно. Но у меня то просто auto = {...}. Просто каждый элемент тоже {...}.
В общем, не нравится мне это решение с плохо связанными между собой auto, decltype и выводом типа шаблона - кто в лес, кто по дрова...
Но ладно, будем знать.

Автор: Qraizer 03.02.12, 12:59
Ну так auto как раз подразумевает вывод типа компилятором. А у него неоднозначность. Попробуй попользовать typeid().name() или decltype со списком инициализации. Другое дело, если ты явно говоришь int = {}, как и в случае параметров функций (initializer_list<int>) или (int[]). Но ведь auto ж.

Автор: D_KEY 03.02.12, 13:04
Мне, в первую очередь, не нравится тот пример, что я описал в #695 посте.
Очень странно ведет себя "вывод типов", особенно по сравнению с развитыми системами типизации, где вывод типов был всегда...
Впрочем, это уже совсем другая тема ;)

Автор: Qraizer 03.02.12, 13:08
Там типы x и y уже выведены по правилам braced-init-list для агрегатных объектов, так что для z уже всё известно. Во втором же случае непонятно даже, можно ли рассматривать вложенные {} как агрегатные.

Автор: D_KEY 03.02.12, 13:11
Цитата Qraizer @
Там типы x и y уже выведены по правилам braced-init-list для агрегатных объектов, так что для z уже всё известно. Во втором же случае непонятно даже, можно ли рассматривать вложенные {} как агрегатные.

Это понятно.
Не понятно, зачем так было проектировать языковый фичи.
У меня такое чувство, что ты меня провоцируешь на оффтоп :D

Автор: Qraizer 03.02.12, 13:18
Ну... вот аналогия.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename T> class complex_number
    {
    public:
      complex_number(T);
    /* ... */
    };
     
    template <typename T> class array
    {
    public:
      explicit array(std::size_t);
    /* ... */
    };
Почему во втором случае конструктору нужно указать explicit, а в первом нет?
Вот чтобы таких косяков со списками инициализаций не было, потому и не однозначность.

Автор: D_KEY 03.02.12, 13:28
Qraizer, мне не понятно, почему auto не может применять свои правила рекурсивно в данном случае.

Автор: Qraizer 03.02.12, 13:58
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x[][] = { {1, 2, 3}, {4, 5, 6} };


Добавлено
Уже не знаю, как ещё понятнее рассказать о неоднозначности намерений программиста, имеющей место в данном случае.

Автор: D_KEY 03.02.12, 14:08
Цитата Qraizer @
Уже не знаю, как ещё понятнее рассказать о неоднозначности намерений программиста, имеющей место в данном случае.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto a = {1, 2, 3, 4, 5, 6} };
    auto b = { {1, 2, 3}, {4, 5, 6} };
     
    auto x = {1, 2, 3};
    auto y = {4, 5, 6};
    auto z = {x, y};

Раз смогли однозначно предложить тип для a, значит можем однозначно предложить тип для b, тем более, если смогли вывести для x, y и z.
Это логично.
Все остальное - негативное следствие других особенностей языка. Уж лучше бы вообще не выводили тип по auto для {1, 2, 3} - это было бы понятнее.
Но это все оффтоп. Можем создать отдельную оффтопную тему про вывод типов :)

Добавлено
Цитата Qraizer @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x[][] = { {1, 2, 3}, {4, 5, 6} };


Это к чему?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x[] = {1, 2, 3, 4, 5, 6};

Автор: Qraizer 03.02.12, 15:38
Цитата D_KEY @
Раз смогли однозначно предложить тип для a, значит можем однозначно предложить тип для b, тем более, если смогли вывести для x, y и z.
В том-то и дело, что нет:
Цитата Qraizer @
Во втором же случае непонятно даже, можно ли рассматривать вложенные {} как агрегатные.
В остальных случаях неоднозначности нет. Ещё раз.
Цитата Qraizer @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class T> void g(T);
     
    g({1,2,3}); // error: no argument deduced for T
Какая сигнатура должна была бы быть выведена, если б было позволено:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void g(std::initializer_list<int>);
или
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void g(int[]);

Цитата D_KEY @
Уж лучше бы вообще не выводили тип по auto для {1, 2, 3} - это было бы понятнее.
Не могу не согласиться. С другой стороны int z[] = {/* ... */} писать удобно, хоть оно и работает только в первом измерении. Так что...
Цитата D_KEY @
Это к чему?
Вот-вот. ;)

P.S. Блин, тяжело писать на шведской клавиатуре без кириллицы.

Автор: Radagast 13.02.12, 19:48
OMG Саттер хочет запилить в стандартную библиотеку поддержку XML/HTML/HTTP/JSON/REST/криптографию/графику итд (смотреть с 1:20:00)
как вам такая идея? :blink:

Автор: niXman 13.02.12, 19:50
а встроенный сервер будет? оО

тут все коммиты в новый стандарт. есть много интересного.

Автор: Flex Ferrum 13.02.12, 19:54
Цитата Radagast @
OMG Саттер хочет запилить в стандартную библиотеку поддержку XML/HTML/HTTP/JSON/REST/криптографию/графику итд (смотреть с 1:20:00)

Ну, обещать - ещё не жениться. :) А сама идея - сомнительна.

Автор: MyNameIsIgor 14.02.12, 05:41
Кто смотрел, раскажите краткую выжимку :)

Автор: B.V. 16.02.12, 12:03
Цитата Radagast @
Саттер хочет запилить в стандартную библиотеку поддержку XML/HTML/HTTP/JSON/REST/криптографию/графику итд

До криптографии я еще понимаю, все платформо-независимо, а вот с графикой я не понимаю вообще, каким же образом?

Автор: D_KEY 16.02.12, 12:22
Цитата B.V. @
а вот с графикой я не понимаю вообще, каким же образом?

Может быть имеется в виду что-то вроде поддержки OpenGL, нечто вроде boost/GIL и т.п.?

Автор: Повстанець 16.02.12, 12:25
Цитата D_KEY @
Может быть имеется в виду что-то вроде поддержки OpenGL
Дык OpenGL то такое дело. Сегодня есть, завтра -- нет. Смысл его в стандарт добавлять?

Автор: MyNameIsIgor 16.02.12, 12:36
Цитата Повстанець @
Дык OpenGL то такое дело. Сегодня есть, завтра -- нет. Смысл его в стандарт добавлять?

Ну, OpenGL сам по себе стандарт... Но вот есть же OpenGL ES для встраиваемых систем, так что становится не очень понятно, что же именно включать. С одной стороны, не все устройства могут реализовать OpenGL, но если включить OpenGL ES, то это станет сильным ограничением...

Автор: D_KEY 16.02.12, 12:37
Цитата Повстанець @
Цитата D_KEY @
Может быть имеется в виду что-то вроде поддержки OpenGL
Дык OpenGL то такое дело. Сегодня есть, завтра -- нет. Смысл его в стандарт добавлять?

Я тоже смысла не вижу :)

Добавлено
Вообще, надо Саттера послушать для начала :)

Автор: DEADHUNT 16.02.12, 14:13
Цитата B.V. @
вот с графикой я не понимаю вообще, каким же образом?

а в чём проблема? для примера посмотри AWT и Swing в Java.

Автор: D_KEY 16.02.12, 14:32
Цитата DEADHUNT @
Цитата B.V. @
вот с графикой я не понимаю вообще, каким же образом?

а в чём проблема? для примера посмотри AWT и Swing в Java.

Зачем это в Стандарте?

Автор: Radagast 16.02.12, 15:04
прошу прощения, под графикой имелся в виду не GUI, а images/audio/video processing
но все равно бред, на который я не обратил бы внимания, если бы это предложил какой-нибудь Вася Пупкин

Автор: Flex Ferrum 28.02.12, 06:19
Вот и к нам пришла SOPA. Джосаттис отказывается издавать свою вторую книгу "The C++ Standard Library" с информацией о новых возможностях STL (из нового стандарта) до тех пор, пока его издатель поддерживает инициативу SOPA:

Цитата
The concrete problem I have is that my publishing company, Pearson Education, supports this act. Or in other words, my publisher has no problem to attack fundamental democratic rights and Internet rules to protect its interests. Now, you might argue that these are also my interests. However in the past years of Guantanamo, the Iraq war, and the financial crisis, I learned that it can't be a democratic reaction to compromise democracy when you are not satisfied with its outcome. This brings us (not only the U.S. but other countries, such as Germany where I am living) to the same level as autocratic countries.

So, in essence, I can't support that Person will use the income of my money to fight against democracy. For this reason, I will stop my work on the 2nd edition of The C++ Standard Library until Pearson stops their support for this act. As this edition is expected to become a bestseller, this might cost me thousands of bucks. However I am old enough to know that there are more important things than money. According to Time for Outrage: Indignez-vous! by Stephane Hessel it's time to shout out loud that I am fed up with all these guys that mean that they again and again can give up fundamental human rights and culture because they think they are right. I like many of these guys and often they are right, but the end does not justify the means.

Fortunately, I am not alone. Read this open letter by Martin Fowler and others to the vice president of Pearson for feedback by many other authors.

Автор: applegame 28.02.12, 19:27
Пришла не только SOPA но еще и PIPA.

Автор: D_KEY 11.03.12, 12:43
Подразумевает ли новый стандарт какой-то способ задать функцию с переменным числом аргументов одного типа?
Допустим есть:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<typename T, typename ... Args>
    void f(const T &a1, const Args& ... args)
    {
       // ...
    }

Но требуется, чтобы все аргументы были типа T.
Можно бы было обойтись std::initializer_list<T>, но мне нужно знать количество аргументов во время компиляции, т.е. sizeof...().
Хотелось бы что-то в духе:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<typename T>
    void f(const T &a1, const T& ... args)
    {
       // ...
    }

Есть ли какой-то относительно простой способ это сделать?

Автор: MyNameIsIgor 11.03.12, 13:05
D_KEY, а static_assert с проверкой всех Args на идентичность T не подойдёт?

Автор: D_KEY 11.03.12, 13:09
Цитата MyNameIsIgor @
D_KEY, а static_assert с проверкой всех Args на идентичность T не подойдёт?

Можно, конечно, только не красиво... Вроде как есть механизм, но не доделанный(ИМХО).

Автор: MyNameIsIgor 11.03.12, 13:15
Цитата D_KEY @
Вроде как есть механизм, но не доделанный(ИМХО).

В чём недоделанный? Ты хочешь перегрузку по указанному типу?

Автор: D_KEY 11.03.12, 13:21
Цитата MyNameIsIgor @
В чём недоделанный? Ты хочешь перегрузку по указанному типу?

Допустим. Впрочем ладно, это уже холивар :) Нет, так нет.

Автор: Qraizer 11.03.12, 14:33
D_KEY, ты можешь проверять тип каждого параметра на соответствие T. Как-то так, например:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename T, typename F, typename ...Args> struct AllSame;
    template <typename T, typename ...Args>             struct AllSame<T, T, Args...> : AllSame <T, Args...> {};
    template <typename T>                               struct AllSame<T, T>                                 {};
     
    template<typename T, typename ... Args>
    void f(const T &a1, const Args& ... args)
    {
      AllSame<T, Args...> dummy;
     
      // ...
    }

Автор: Qraizer 12.03.12, 03:05
Хм... Я что-то не так написал или в натуре просто "ещё не реализовано"? Кто уже вариадики пользовал серьёзно, что тут может быть не по Стандарту?

Автор: niXman 12.03.12, 09:18
Цитата
sorry, unimplemented: cannot expand 'Args ...' into a fixed-length argument list

да, это недореализованно.

Автор: XandoX 12.03.12, 10:08
Цитата niXman @
Цитата
sorry, unimplemented: cannot expand 'Args ...' into a fixed-length argument list

да, это недореализованно.


а можно по подробнее, что конкретно не реализовано, а то я что-то никак не пойму, откуда тут fixed-length argument list?

и в чем его принципиально отличие от следующего кода (который кстати компилируется)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class T, class ... Args> struct all_same;
    template<class T, class ... Args> struct all_same<T, T, Args ...> : all_same<T, Args...> {};
    template<class T> struct all_same<T, T> {};
     
    template<class T, class ...Args>
    void f(const T& t, const Args& ... args) {
        all_same<T, Args...> dummy;
    }

Автор: Повстанець 12.03.12, 10:12
Цитата D_KEY @
Есть ли какой-то относительно простой способ это сделать?
Писать лень, могу на пальцах прикинуть: аргументы в список типов.
далее, по enable_if в возвращаемый результат либо вручную пишешь функтор, проверяющий все ли одинаковы, либо количество повторений должно быть равно длинне списка. Вроде для второго в Loki всё есть.

Автор: Qraizer 12.03.12, 11:05
Цитата niXman @
да, это недореализованно.
Ну это радует. В смысле, радует, что я это правильно себе представляю, мне-то пока негде разгуляться с вариадиками. XandoX, я вот тоже не пойму, чем мешает ещё один шаблонный параметр в первичном шаблоне. Впрочем, для указанного случая это не принципиально. Я сначала предполагал заюзать F, но оказалось, что для нужных частичных специализаций он не требуется, Args и сам справляется.
D_KEY, я так полагаю, подобные вещи предполагалось возложить на концепты. Вариадики не виноваты, что с концептами такая неприятность случилась.

Добавлено
Да, clang съел и не подавился. <_<

Автор: applegame 02.05.12, 07:12
Жаль, что в новый стандарт так и не ввели синтаксический сахар для реализации свойств объекта. Печаль...

Автор: MyNameIsIgor 30.05.12, 05:32
Меня глючит, или в C++11 грозились добавить rope? Сейчас полистал Стандарт - нету :no-sad:

Автор: applegame 30.05.12, 11:01
Цитата MyNameIsIgor @
Меня глючит, или в C++11 грозились добавить rope? Сейчас полистал Стандарт - нету :no-sad:

Погуглил. Ты про класс для манипулирования очень длинной строкой? Наверное решили, что оно слишком специфично, чтобы запиливать в STL.

Автор: Flex Ferrum 30.05.12, 11:09
Цитата MyNameIsIgor @
Меня глючит, или в C++11 грозились добавить rope? Сейчас полистал Стандарт - нету :no-sad:

Эммм... Может быть для этих целей deque подойдёт?

Автор: MyNameIsIgor 30.05.12, 11:45
Цитата Flex Ferrum @
Эммм... Может быть для этих целей deque подойдёт?

Ну, если chat_traits ручками учитывать, то да, подойдёт...

Автор: Flex Ferrum 29.10.12, 08:15
Итак, немного инфы с последнего митинга комитета. Источник: тыц.
Из интересного:
1. Следующий (помежуточный) стандарт будет, судя по всему, в 2014-ом году.
2. Есть вероятность, что введут полиморфные лямбды. По крайней мере, это обсуждается.
3. (кстати, да) вывод типов для обычных функций (а не только lambda).

Автор: niXman 29.10.12, 08:27
Цитата Flex Ferrum @
в 2014-ом году.

угу. уже реализовывают в 4.8 ветке: http://gcc.gnu.org/gcc-4.8/changes.html
Цитата

G++ now supports a -std=c++1y option for experimentation with features proposed for the next revision of the standard, expected around 2017. Currently the only difference from -std=c++11 is support for return type deduction in normal functions, as proposed in N3386.


Цитата Flex Ferrum @
полиморфные лямбды.

хз что это, и зачем..
жду static_if()

Автор: Flex Ferrum 29.10.12, 08:30
Цитата niXman @
хз что это, и зачем..

А там в статье указано. Это из серии:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::transform(vec.begin(), vec.end(), vec.begin(), [](auto x) {return x * 2;});

Т. е. когда вывод типов аргументов лямбды делается автоматически компилятором.

Автор: B.V. 29.10.12, 08:32
Мне интересно, а планируется по стандарту расширять STL? split/join там добавить, к примеру

Автор: niXman 29.10.12, 08:35
Цитата Flex Ferrum @
[](auto x) {return x * 2;}

тогды нужно)
Цитата B.V. @
а планируется по стандарту расширять STL?

да.
на счет split/join не уверен, но либы приниматься будут. специально для этого создали группу.
ща ссылку найду.

Автор: Flex Ferrum 29.10.12, 08:36
Про полиморфные лямбды: N3418.

Автор: MyNameIsIgor 29.10.12, 08:38
Цитата Flex Ferrum @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::transform(vec.begin(), vec.end(), vec.begin(), [](auto x) {return x * 2;});

Да тут даже auto можно выпилить...

Автор: Flex Ferrum 29.10.12, 08:38
Цитата B.V. @
split/join там добавить, к примеру

N3430 - это про split.

Добавлено
Цитата MyNameIsIgor @
Да тут даже auto можно выпилить...

Что Саттер сотоварищи и предлагает. :)

Автор: MyNameIsIgor 29.10.12, 08:39
Цитата Flex Ferrum @
Цитата MyNameIsIgor @
Да тут даже auto можно выпилить...

Что Саттер сотоварищи и предлагает. :)

Они бы сразу это предлагали...

Автор: Flex Ferrum 29.10.12, 08:40
А вот про join ничего нет. Видимо, функциональности ostream_interator'ов для этого достаточно.

Автор: niXman 29.10.12, 08:41
Цитата MyNameIsIgor @
Они бы сразу это предлагали

снова отложат до следующего стандарта)

Автор: MyNameIsIgor 29.10.12, 08:42
Ребята, а чего там с мультиметодами? Контрактами? Концептами?

Автор: Flex Ferrum 29.10.12, 08:44
Цитата MyNameIsIgor @
Концептами?

Конецпты обсуждались на прошлом митинге:
Цитата
While not a proposal, an over 100 page progress report on Concepts was reviewed. Quite a lot has happened with concepts.
University of Indiana, Texas A&M university, A9, and Alex Stepanov has gotten together to look at simplifying Concepts (which were removed in Frankfurt due to serious issues found at that time). Their effort showcases a work in progress where a few controversial issues have been greatly simplified. They started work based on Alex Stepanov's recent book on Elements of Programming. The aim was to make concrete Concepts only based on mathematically sound principles. This means there are now far fewer concepts, and no concept maps. Many Concepts would embody a collection of ideas that were mathematically linked. In so doing, they have reduced the frightful proliferation of over 100 concepts that were introduced until Concept was removed. This new proposal can have almost all the Concepts fit on a single slide. This looks very promising.

Автор: B.V. 29.10.12, 09:37
Цитата Flex Ferrum @
Про полиморфные лямбды: N3418.

Короче, идут по пути упрощения синтаксиса. Это хорошо

Автор: applegame 29.10.12, 09:53
Надеюсь новые стандарты будут приниматься быстрее, чем нынешний.

Автор: Radagast 31.10.12, 18:27
глубоко вдохнули...
Цитата Herb Sutter
In my talk on Friday, there will be announcements of broad interest to C++ developers on all compilers and platforms. Please help spread the word.

http://herbsutter.com/2012/10/29/the-futur...st-this-friday/

Автор: Flex Ferrum 31.10.12, 18:40
У нас это можно будет смотреть в 23:45, пятница.

Автор: Radagast 03.11.12, 09:08
что успел законспектировать, выложил на Хабре

Автор: niXman 03.11.12, 09:30
> SG4, Networking: Kyle Kloepper (Riverbed). Всё, что связано с сетью, сонетами и HTTP.
сокетами*

странно, почему-то был уверен, что это место по праву принадлежит Chris Kohlhoff.
и да, считаю, что http как и другие прикладные протоколы в стандарте - бред.

> SG7, Reflection: Chandler Carruth (Google). Рефлексия во время компиляции.
где об этом можно прочитать подробнее?

> SG9, Ranges: Marshall Clow (Qualcomm). Использование диапазонов вместо пар итераторов в стандартной библиотеке, в т.ч. в контейнерах и алгоритмах.
а вот это ооочень нужно!

> SG11 в процессе формирования и будет посвящена базам данных.
снова бред %)

> каждая Study Group может публиковать свои TS (technical specification) независимо.
привет, хаос!

> Constexpr хотят расширить, чтобы там можно было писать больше одного statement.
constexpr`ы, сами по себе бесценная плюшка, но а это сделает их абсолютно бесценными!

> Герб уже работает над заявкой в Комитет, посвященной сборщику мусора.
ну хз-хз... текущая спецификация мне говорит что "нинужна". чем будет новая спецификация отличаться - хз-хз..

Добавлено
> Кроме того, запущен сайт isocpp.org ..., который должен стать сайтом №1 для новостей про C++
хм.. там не только о самом С++, там еще и новости про всякие С++ библиотеки(кстати, нужно опубликовать свои проекты там же), и новости о записях в блогах...

Добавлено
касательно баз данных и http, я наверное все же неправильно понял. эти плюшки не свалятся на голову стандартизаторов языка, и таким образом, по сути, не будут являться частью стандарта? если "да", тогда вообще не понимаю, зачем об этом писать/сообщать? POCO(к примеру), как выходила когда ей вздумается, так и будет выходить когда ей вздумается. мне на это начхать.

наверное, все же, я все неправильно понял..

Автор: applegame 03.11.12, 12:56
Цитата niXman @
> SG9, Ranges: Marshall Clow (Qualcomm). Использование диапазонов вместо пар итераторов в стандартной библиотеке, в т.ч. в контейнерах и алгоритмах.

Цитата niXman @
> Герб уже работает над заявкой в Комитет, посвященной сборщику мусора.

Здравствуй D!

Автор: niXman 03.11.12, 12:56
Цитата applegame @
Здравствуй D!

не, это к александреску ;)

Автор: applegame 03.11.12, 13:02
Цитата niXman @
не, это к александреску ;)
Я к тому, что C++ все сильнее и сильнее становится похожим на D.

Автор: MyNameIsIgor 03.11.12, 14:42
Цитата applegame @
Я к тому, что C++ все сильнее и сильнее становится похожим на D.

И как в D выглядит inplace_merge?

Автор: niXman 03.11.12, 14:45
Цитата MyNameIsIgor @
как в D выглядит inplace_merge?

а как в с++?
что-то не помню о таком...

Автор: MyNameIsIgor 03.11.12, 14:47
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template< class BidirIt >
    void inplace_merge( BidirIt first, BidirIt middle, BidirIt last );
    template< class BidirIt, class Compare>
    void inplace_merge( BidirIt first, BidirIt middle, BidirIt last, Compare comp );

Автор: niXman 03.11.12, 14:49
аа, это алгоритмы...

Автор: Radagast 03.11.12, 15:19
niXman
сонеты в С++ - самое важная плюшка! :)
*исправил
Цитата
> SG7, Reflection: Chandler Carruth (Google). Рефлексия во время компиляции.
где об этом можно прочитать подробнее?

пока что хз, в ближайшем будущем обещают форум с отдельными разделами для каждой SG http://isocpp.org/forums
Цитата
>каждая Study Group может публиковать свои TS (technical specification) независимо
привет, хаос!

насколько я понял из презентации, независимость только в расписании. если 2 части библиотеки никак друг от друга не зависят, но почему бы не выпускать работу тогда, когда она сделана...
насчет сборщика мусора, там уже нафлудили в комментах, с объяснениями зачем он нужен.
Цитата
я наверное все же неправильно понял. эти плюшки не свалятся на голову стандартизаторов языка

не уверен, но вроде все же свалятся. надо внимательно курить раздел сайта, посвященный процессу стандартизации, надеюсь там есть подробности

Автор: D_KEY 04.11.12, 17:00
Цитата Radagast @
насчет сборщика мусора, там уже нафлудили в комментах, с объяснениями зачем он нужен.

Ну... Нормальный сборщик на С++ все равно не ляжет(из-за указателей). Будет консервативный - профита от него немного.

Автор: applegame 05.11.12, 13:28
Цитата MyNameIsIgor @
И как в D выглядит inplace_merge?
Никак. В данный момент эта функция отсутствует в Phobos.

Автор: MyNameIsIgor 06.11.12, 05:21
Цитата applegame @
В данный момент эта функция отсутствует в Phobos.

Вот это fail :D А как бы она выглядела с range'ами?

Автор: applegame 06.11.12, 06:12
Цитата MyNameIsIgor @
Вот это fail :D А как бы она выглядела с range'ами?
Да их фобос вообше сплошной fail. Каждый раз когда пытаюсь написать что-нибудь на D, нарываюсь на грубые недоработки. То пляски с бубном вокруг shared-атрибута, то жопа с контейнерами. Вот недавно понадобилось вставить элемент в список (DList по ихнему, std::list по нашему), запомнить итератор диапазон на этот элемент и потом когда-нибудь удалить этот элемент из списка. Конечно же я ожидал что смогу получить диапазон на свежевставленный элемент (тупо конец списка) за константное время. Авотфиг! От огорчения ажно запостил вопрос им на форум, вот ответ:
Цитата
There is no way to do that in constant time with current dlist interface.
Это не просто fail, это epic fail.
Если интересно, можете ужаснуться вот тут: http://forum.dlang.org/thread/lozpofrboxsf...forum.dlang.org

Поэтому я понятия не имею как бы она выглядела с range`ами и иметь не хочу.

Автор: MyNameIsIgor 06.11.12, 06:16
applegame, в D я разочаровался уже давно. Но вот range'и мне не понятны - как же всё же их использовать там, где надо три итератора? Да и Степанов по этому поводу сказал про Александреску: моська лает на слона.

Автор: applegame 06.11.12, 06:17
Я вообще разочарован в этих диапазонах и профит от них мне теперь кажется весьма сомнительным.

Добавлено
Цитата MyNameIsIgor @
как же всё же их использовать там, где надо три итератора?
Ну каждый диапазон - суть два итератора. Так что в случае с inplace_merge можно использовать два диапазона.

Автор: D_KEY 06.11.12, 06:55
boost/range/algorithm/inplace_merge.hpp

Автор: MyNameIsIgor 06.11.12, 07:23
Цитата D_KEY @
boost/range/algorithm/inplace_merge.hpp

Делаем range вокруг итераторов, а потом делаем итератор вокруг range'а :jokingly:

Автор: D_KEY 06.11.12, 07:29
Цитата MyNameIsIgor @
Делаем range вокруг итераторов, а потом делаем итератор вокруг range'а :jokingly:

А мне как раз нравится... Нужны и range и iterator. Первый, кстати, все равно есть в stl, только на концептуальном уровне. Так что зря Степанов критикует range...

Автор: applegame 06.11.12, 07:40
Цитата D_KEY @
Так что зря Степанов критикует range...
Степанова надо самого попинать за корявый basic_string.

Автор: MyNameIsIgor 06.11.12, 07:43
Цитата applegame @
Степанова надо самого попинать за корявый basic_string

Было бы клёво, но, ЕМНИП, это не его творение...

Добавлено
Цитата D_KEY @
Так что зря Степанов критикует range...

В том случае речь шла о замене итераторов на range'и вообще, а не добавлении к итераторам.

Автор: niXman 06.11.12, 07:44
уже год как отказался от итераторов в пользу boost.range, и не жалею. теперь еще сильнее хочу видеть их в стандарте.

Автор: D_KEY 06.11.12, 07:50
Цитата applegame @
Степанова надо самого попинать за корявый basic_string.

Вроде не его это детище. Особенно судя по тому, как его натягивали на stl поверх собственного "строкового" интерфейса. Да и в стандарте отдельно описан.

Добавлено
Цитата MyNameIsIgor @
В том случае речь шла о замене итераторов на range'и вообще, а не добавлении к итераторам.

Кстати, ссыль есть?

Автор: MyNameIsIgor 06.11.12, 07:52
Цитата D_KEY @
Кстати, ссыль есть?

Там была большая лекция в Яндексе. Поищи, по-моему, там две части. Яндексоиды выкладывали.

Автор: D_KEY 06.11.12, 07:54
Цитата MyNameIsIgor @
Там была большая лекция в Яндексе. Поищи, по-моему, там две части. Яндексоиды выкладывали.

Ааа, я кажется смотрел, но мало что помню... :D

Автор: NeoApostol 06.11.12, 08:56
Цитата applegame @
Надеюсь новые стандарты будут приниматься быстрее, чем нынешний.

Следующий насколько помню в 2017

Автор: NeoApostol 06.11.12, 14:55
Цитата niXman @
жду static_if()

что это такое?

Автор: Kray74 06.11.12, 15:13
Preliminary proposal for a static if [PDF]

Автор: applegame 06.11.12, 16:02
static_if не помешал бы, а то сейчас приходится применять сильное колдунство.

Автор: MyNameIsIgor 06.11.12, 19:18
Цитата applegame @
static_if не помешал бы, а то сейчас приходится применять сильное колдунство.

Всё-таки какие разные вещи люди ожидают... Мне бы вот концепты, мультиметоды, модули, контракты, улучшения лямбд (полиморфность и список захвата), а тут вот уже второй за static_if...

Автор: niXman 06.11.12, 19:25
Цитата MyNameIsIgor @
концепты, мультиметоды, модули, контракты

не испытываю острой необходимости в этом.
улучшенные лямбды - да, нужно.

но а static_if(), это чуть ли не самое нужное для людей, использующих метапрограммирование. для остального оно почти не нужно.

Автор: MyNameIsIgor 06.11.12, 19:38
Цитата niXman @
не испытываю острой необходимости в этом.

Как это печально....

Автор: niXman 06.11.12, 19:50
чья бы корова...

Автор: applegame 06.11.12, 20:50
Цитата niXman @
но а static_if(), это чуть ли не самое нужное для людей, использующих метапрограммирование. для остального оно почти не нужно.
Ну не самое нужное. Таки можно выкрутиться при помощи всяких std::enable_if и проч.

Автор: niXman 06.11.12, 20:51
Цитата applegame @
Таки можно выкрутиться при помощи всяких std::enable_if и проч.

но читабельность кода при этом будет в разы хуже, чем при использовании static_if()

Автор: D_KEY 06.11.12, 21:44
Цитата MyNameIsIgor @
мультиметоды
контракты

Так хотят?

Цитата
список захвата

А там что планируется улучшить?

Добавлено
Цитата niXman @
не испытываю острой необходимости в этом.

Думаю это ты не до конца вкурил... Концептов, наверно, больше всего жду :) Очень клевый язык с ними будет, этот наш С++ :D

Автор: korvin 07.11.12, 04:56
Цитата MyNameIsIgor @
модули

Хех, а D_KEY, помнится, говорил, что они не нужны. =)

В чем причина твоего ожидания модулей?

Автор: MyNameIsIgor 07.11.12, 05:28
Цитата korvin @
Хех, а D_KEY, помнится, говорил, что они не нужны. =)

Там был другой контекст обсуждения. В том виде, в котором они есть в делфи или в питоне, imho, действительно были бы лишними.
Цитата korvin @
В чем причина твоего ожидания модулей?

Хочу отделения физического распределения на файлы и логического разделения на модули. Хочу shared либы/модули, независимые от компилятора. Хочу их динамическую загрузку. Хочу ABI. Ну, вообще размечтался :)
Цитата D_KEY @
Так хотят?

Ну, предложения то есть... Я просто надеюсь :)
Цитата D_KEY @
А там что планируется улучшить?

Возможность move'ить в список захвата. И forward'ить. Сейчас таких возможностей нет.
Цитата niXman @
но читабельность кода при этом будет в разы хуже, чем при использовании static_if()

Меня вот беспокоит читабельность и производительность кода без мультиметодов и сопоставления с образцом, когда приходится делать визитор или свои наколеночные мультиметоды. А static_if... ну, не надо до такой степени метапрограммить на плюсах :)

Автор: niXman 07.11.12, 05:30
Цитата MyNameIsIgor @
не надо до такой степени

кто на что учился.

Автор: MyNameIsIgor 07.11.12, 05:36
Цитата niXman @
чья бы корова...

Цитата niXman @
кто на что учился.

Простите, но я не понимаю ваших высказываний...

Автор: niXman 07.11.12, 05:38
это ничего

Автор: XandoX 07.11.12, 06:00
Цитата MyNameIsIgor @
и сопоставления с образцом

это патерн матчинг что ли? его вводить собираются?

Автор: MyNameIsIgor 07.11.12, 06:04
Цитата XandoX @
это патерн матчинг что ли?

Да.
Цитата XandoX @
его вводить собираются?

Нет.

Автор: XandoX 07.11.12, 06:05
Цитата MyNameIsIgor @
Нет.

блин :(

Автор: niXman 07.11.12, 06:09
XandoX, а для чего он Вам?

Автор: applegame 18.11.12, 08:32
На последнем сборище разработчиков LLVM некий Doug Gregor из Apple демонстрировал концепцию модулей для C++. Бва-ха-ха-ха-ха. http://llvm.org/devmtg/2012-11/Gregor-Modules.pdf

Автор: Kray74 18.11.12, 10:09
В предлагаемом решении могут быть потенциальные проблемы, т.к. не допускается влияние макросов на модули, но некоторые хедеры рассчитаны на настройку с помощью макросов.

Автор: Алексей_Л 18.11.12, 11:55
Цитата Kray74 @
В предлагаемом решении могут быть потенциальные проблемы, т.к. не допускается влияние макросов на модули, но некоторые хедеры рассчитаны на настройку с помощью макросов.

как правило это относится к условной компиляции, т.е. когда часть модуля не включается, если что-то задефайнено
надо подумать, реализовать это как-то иначе, например, как разные версии модулей или сделать отдельный механизм для передачи флагов настроек в модуль..

Автор: Kray74 18.11.12, 12:03
Компилировать все возможные версии никакого места не хватит, а вот отдельный механизм, не зависящий от препроцессора (возможно с использованием static if), был бы кстати.

Автор: Qraizer 18.11.12, 15:47
Как будто он первый. "Дизайн и эволюцию" не читал, что ли? Ничего нового с предложений 80-х годов я не увидел. Заменить препроцессор на модули - это шило на мыло. Решаем одни проблемы, вводим новые.

Автор: Flex Ferrum 23.04.13, 13:52
На днях WG21 разродился целой кучей бумаг. Из интересного:
std::optional - название говорит само за себя.
std::make_unique - тут тоже, вроде бы, понятно. Аналог std::make_shared.
Generic (polymorphic) lambda expression - позволяет использовать auto в качестве типа параметров lambda-выражений.
Wording Changes for Generalized Lambda-Capture - обобщённые списки захвата лямбд. В частности, позволяют определять в списках захвата новые переменные вместе с инициализаторами.
Runtime-sized arrays with automatic storage duration - массивы перменной длины из C.
C++ Dynamic Arrays (dynarray) - как говорят авторы, альтернативный вариант реализации массивов переменной длины из C. Предлагают специальный библиотечный тип (dynarray), который может иметь special handling внутри компилятора и оптимизироваться при использовании в качестве типа автоматической переменной.

Автор: XandoX 23.04.13, 13:57
а зачем все эти массивы переменной длины если вектор есть?

Добавлено
ну то есть в с понятно зачем они, в вот в с++ не понятно

Автор: Flex Ferrum 23.04.13, 13:59
Цитата XandoX @
а зачем все эти массивы переменной длины если вектор есть?

Вектор сложно заставить использовать память на стеке для аллокации хранилища. По этому и требуются такие вот костыли.

Автор: MyNameIsIgor 23.04.13, 14:00
Цитата XandoX @
а зачем все эти массивы переменной длины если вектор есть?

Потому что выделять память на стеке гораздо быстрее, чем в куче. А сделать аллокатор для стека не представляется возможным... а может и возможно, но imho костыльно будет.

Добавлено
По прежнему жду концептов, мультиметодов, контрактов, модулей, динамически загружаемых библиотек... Хех...

Автор: Flex Ferrum 23.04.13, 14:03
Цитата MyNameIsIgor @
По прежнему жду концептов, мультиметодов, контрактов, модулей, динамически загружаемых библиотек... Хех...

Я тут не всё привёл. Лучше держать руку "на пульсе". В смысле, на RSS-е. :D

Автор: MyNameIsIgor 23.04.13, 14:08
Цитата Flex Ferrum @
Я тут не всё привёл. Лучше держать руку "на пульсе".

Да читал я документы!
Цитата
- А давайте замутим await как в сисярпе?
- Нееее, нам надо быть первыми дебилами, которые запилят OpenMP непосредственно в язык!
- Да ну его, этот ваш OpenMP, вот непонятную, не обкатанную херь Cilk - вот его давай, да!

Ну, и в таком духе тащат в язык всякую херню :bad:

Автор: Kray74 23.04.13, 14:18
Цитата MyNameIsIgor @
А сделать аллокатор для стека не представляется возможным... а может и возможно, но imho костыльно будет.

stack_alloc

Автор: MyNameIsIgor 23.04.13, 15:48
Цитата Kray74 @
Цитата MyNameIsIgor @
А сделать аллокатор для стека не представляется возможным... а может и возможно, но imho костыльно будет.

stack_alloc

Как я понял, там размер параметром шаблона задаётся - костыльно, да, по сравнению с runtime-sized массивами.

Автор: Radagast 24.04.13, 09:42
извините, я не в теме, а как можно вообще разместить на стеке массив динамической длины? оО

Автор: applegame 24.04.13, 09:46
Цитата Radagast @
извините, я не в теме, а как можно вообще разместить на стеке массив динамической длины? оО
Она (длина) условно динамическая. Размер массива доолжен быть известен при входе в функцию (например, размер - один из аргументов функции), тогда компилятор при резервировании места для локальных переменных, может сразу зарезервировать место под массив. Вроде так.
AFAIK, изменять размер уже созданного массива нельзя.

Автор: MyNameIsIgor 24.04.13, 10:09
Цитата Radagast @
извините, я не в теме, а как можно вообще разместить на стеке массив динамической длины?

Ну, а как происходит резервирование стека? Простым изменением значения регистра. Никто не мешает менять его на любое число.
Цитата applegame @
Она (длина) условно динамическая. Размер массива доолжен быть известен при входе в функцию (например, размер - один из аргументов функции), тогда компилятор при резервировании места для локальных переменных, может сразу зарезервировать место под массив. Вроде так.

Очередная показуха своей безграмотности? :facepalm:

Автор: liss 24.04.13, 10:24
Цитата MyNameIsIgor @
там размер параметром шаблона задаётся - костыльно, да, по сравнению с runtime-sized массивами

runtime-sized платформо-независимо не получится (и потому boost от этого отказался), но вообще-то есть _malloca в VC++ и alloca в gcc, было бы желание.

Автор: MyNameIsIgor 24.04.13, 10:56
Цитата liss @
runtime-sized платформо-независимо не получится (и потому boost от этого отказался), но вообще-то есть _malloca в VC++ и alloca в gcc, было бы желание.

Если есть реализации, то почему кроссплатформенно не получится?
Мне кажется, что там проблема в куче заботливо разложенных граблей...

Автор: liss 24.04.13, 11:05
мотивировка была простая: эти функции не часть какого-либо стандарта (для буста это означает, что будут поддерживаться лишь полтора конкретных компилятора, и без гарантий на будущее).
написать алокатор для конкретного случая нетрудно. граблей будет ровно столько же, сколько в реализации n3662, т.е. придется соблюдать определенные правила.

Автор: applegame 24.04.13, 11:49
Цитата niXman @
рыбятки, тема-то была не изгажена ;)
MyNameIsIgor любую тему изгадит. Вместо того чтобы указать, что именно неверно (как и делают нормальные люди) он предпочитает грубить. Что касается моей "отсебятины", то я ошибся в том, что место под массив выделяется не на входе в функцию, а в точке декларации массива.

Цитата MyNameIsIgor @
Мне надоело кидать зёрна истины в бетонную стену вашего разума - только и всего. Или вы полагаете, что я вам чем-то обязан и буду "оставаться в топике" до второго пришествия?
Предлагаю вернуться к этой теме в HolyWars, если вы все еще считаете что вы правы. Вот мой последний ответ уже с сылкой на сайт Microsoft - Есть ли будущее у Microsoft?

Автор: amk 25.04.13, 16:46
Вообще-то alloca в gcc выделяет память не в стеке а в куче. И возвращает ссылку на выделенную память (аналогично malloc). Просто он отслеживает эти ссылки и освобождает эту память, как только выяснит, что произошёл выход из вызвавшей его функции.

Автор: niXman 25.04.13, 17:27
Цитата amk @
Вообще-то alloca в gcc выделяет память не в стеке а в куче.

а можно взглянуть на пруф?
а то я только это нашел, но оно для Sparc32.

Автор: cppasm 25.04.13, 17:59
Оно везде такое. alloca() на стеке память выделяет.

Автор: liss 25.04.13, 19:42
http://man7.org/linux/man-pages/man3/alloca.3.html
Цитата
The alloca() function allocates size bytes of space in the stack frame of the caller.

Автор: niXman 25.04.13, 19:50
судя по коду для спарк32, оно так и есть.
просто хотелось бы увидеть код для i386.

Автор: amk 26.04.13, 20:20
niXman, ты же сам сборки gcc делаешь. У тебя должны быть исходники, в том числе и alloca.

Но, похоже, вы правы. Посмотрел сейчас в заголовке - alloca реализуетсячерез встроенную функцию компилятора __builtin_alloca. А это скорее всего означает, что компилятор выделяет память на стеке. Скорее всего просто сдвигает вершину стека и возвращает новую его позицию. Возможно как-то влияет на компиляцию функции, чтобы учесть, что стек сдвинут.
Реализуется скорее всего цепочкой инструкций типа
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    mov ax,<size>
    sub sp,ax
    mov ax,sp

В DECUS C (PDP-11, RT-11 или RSX-11) за это отвечала обычная функция. В нём управление стеком позволяло произвольно сдвигать вершину стека. Эта функция выбирала из стека адрес возврата, сдвигала указатель стека, копировала его в регистр 0 и выполняла переход на выбранный ранее адрес возврата.

Автор: niXman 26.04.13, 21:00
Цитата amk @
У тебя должны быть исходники, в том числе и alloca.

mingw, в качестве CRT, использует msvcrt.dll. а где взять эти исходники, я не в курсе.

Автор: amk 28.04.13, 14:50
Я там выше написал, что посмотрел в malloc.h как объявлены _alloca и alloca. Там написано, что
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #define alloca(x) __builtin_alloca((x))
то есть это реализуется встроенными средствами самого компилятора.

Автор: Flex Ferrum 16.05.13, 07:41
А вот и свеженький драфт C++14.

Добавлено
Бинго! init-capture попала в стандарт!
И auto-тип для аргументов лямбд тоже. :)

Автор: Flex Ferrum 16.05.13, 08:41
Цитата
The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4)
whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause
and trailing-return-type respectively. For a generic lambda, the closure type has a public inline function call
operator member template (14.5.2) whose template-parameter-list consists of one invented type templateparameter
for each occurrence of auto in the lambda’s parameter-declaration-clause, in order of appearance.
The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares
a function parameter pack (8.3.5). The return type and function parameters of the function call
operator template are derived from the lambda-expression’s trailing-return-type and parameter-declarationclause
by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with
the name of the corresponding invented template-parameter.

:victory: Generic-лямбды мало того, что могут принимать аргументы любых типов, так ещё и любое количество аргументов! Интересно, в каком gcc их реализуют? 4.9?

Добавлено
Туда же:
Цитата
An array of runtime bound shall only be used as the type of a local object with automatic storage duration.
If the size of the array exceeds the size of the memory available for objects with automatic storage duration,
the behavior is undefined.100 It is unspecified whether a global allocation function (3.7.4) is invoked to
obtain storage for the array. If it is invoked, the corresponding global deallocation function is invoked to
release the storage after the lifetime of the array has ended.101

(8.3.4)
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <class T>
    class optional
    {
    public:
    typedef T value_type;
    // 20.6.4.1, constructors
    constexpr optional() noexcept;
    constexpr optional(nullopt_t) noexcept;
    optional(const optional&);
    optional(optional&&) noexcept(see below );
    constexpr optional(const T&);
    constexpr optional(T&&);
    template <class... Args> constexpr explicit optional(in_place_t, Args&&...);
    template <class U, class... Args>
    constexpr explicit optional(in_place_t, initializer_list<U>, Args&&...);
    // 20.6.4.2, destructor
    ~optional();
    // 20.6.4.3, assignment
    optional& operator=(nullopt_t) noexcept;
    optional& operator=(const optional&);
    optional& operator=(optional&&) noexcept(see below );
    template <class U> optional& operator=(U&&);
    template <class... Args> void emplace(Args&&...);
    template <class U, class... Args> void emplace(initializer_list<U>, Args&&...);
    // 20.6.4.4, swap
    void swap(optional&) noexcept(see below );
    // 20.6.4.5, observers
    constexpr T const* operator->() const;
    T* operator->();
    constexpr T const& operator*() const;
    T& operator*();
    constexpr explicit operator bool() const noexcept;
    constexpr T const& value() const;
    T& value();
    template <class U> constexpr T value_or(U&&) const&;
    template <class U> T value_or(U&&) &&;
    private:
    bool init; // exposition only
    T* val; // exposition only
    };

Автор: B.V. 16.05.13, 08:51
Цитата Flex Ferrum @
Бинго! init-capture попала в стандарт!

А можно вкратце, что это и какая с него практическая польза?

Автор: Qraizer 16.05.13, 08:52
Ну чё, скоро в std добавят функцию
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<typename ...Args1>
    template<typename ...Args2>
    std::tuple<Args1...> solve_current_problem(Args2...);
и программировать станет скучно.

Автор: Flex Ferrum 16.05.13, 08:56
Цитата B.V. @
А можно вкратце, что это и какая с него практическая польза?

Что-то вроде такого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector<int> nums(10);
     
    std::generate(nums.begin(), nums.end(), [n = 0]() mutable {return n++;});


Добавлено
Цитата Qraizer @
и программировать станет скучно.

Ой, не знаю... Ой, не уверен. :D

Автор: niXman 25.05.13, 07:51
Цитата Qraizer @
Ну чё, скоро в std добавят функцию
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<typename ...Args1>
    template<typename ...Args2>
    std::tuple<Args1...> solve_current_problem(Args2...);
и программировать станет скучно.

ну, нечто подобное уже сейчас можно использовать:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    #include <tuple>
    #include <typeinfo>
     
    template<typename... Args1, typename... Args2>
    std::tuple<Args1...> func(Args2&&... args) {
        return std::make_tuple(args...);
    }
     
    int main() {
        auto r = func<char, double, int>(3, 3.14, 'c');
        
        std::cout << "0:" << typeid(std::get<0>(r)).name() << std::endl;
        std::cout << "1:" << typeid(std::get<1>(r)).name() << std::endl;
        std::cout << "2:" << typeid(std::get<2>(r)).name() << std::endl;
    }

вывод:
Цитата

0:c
1:d
2:i

Автор: Flex Ferrum 25.05.13, 07:57
Цитата niXman @
ну, нечто подобное уже сейчас можно использовать:

Ты явно не понял прикола. :)

ЗЫ: А когда LWS перейдёт из режима R/O в полнофункциональный?

Автор: niXman 25.05.13, 08:49
Цитата Flex Ferrum @
Ты явно не понял прикола.

ах да, я на название функции не обратил внимания =)
Цитата Flex Ferrum @
когда LWS перейдёт из режима R/O в полнофункциональный?

надеюсь, к концу следующей недели.

Автор: Adil 25.05.13, 08:55
Во, я всегда говорю - имя функции должно быть не больше 2-3 символов, всё равно никто не читает.

Автор: reinterpret_alexey 21.06.13, 14:29
А кто-нибудь пробовал прикручивать новый компилятор, например, от Vs2012 к старой (например, Vs2010) студии ? Чтобы она совмещалась с последней версией стандарта. Уж очень мне нравятся все эти сахарные обновляшечки. Без initializer_list вот очень туго живется.

Автор: Flex Ferrum 21.06.13, 14:59
Я пробовал прикручивать компилятор от 2010-ой к 2008-ой. Вроде бы получалось. Делал посредством полной замены содержимого директории с компилятором (и директорий с заголовочными файлами и библиотеками). Наверное, и в твоем случае это может получиться.

Автор: reinterpret_alexey 21.06.13, 16:18
Flex Ferrum

Нет, не получается ...

Цитата
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(153,5): error MSB6006: "CL.exe" завершилась с кодом -1073741515.


Видимо, разница слишком велика (vs2012 у меня вылетает, как я говорил).

Автор: MyNameIsIgor 27.06.13, 18:14
Судя по, в новой студии наконец-то появятся variadic'и.

Автор: Axis 28.06.13, 04:19
Цитата MyNameIsIgor @
Судя по, в новой студии наконец-то появятся variadic'и.
Ноябрьский CTP компилятор?

Автор: Kray74 28.06.13, 06:10
Цитата Axis @
Ноябрьский CTP компилятор?

Глючная полурабочая поделка. На вариадиках я его особо не гонял, но к примеру tuple с более чем 7 шаблонными аргументами он не переварил.
Unified initialization работает только в тривиальных случаях. Defaulted и deleted функций вообще нет, и что-то я не нашел упоминания о них в статье по ссылке.

Автор: applegame 29.06.13, 04:50
Цитата Axis @
Ноябрьский CTP компилятор?
Похоже на то :) в ноябрьском вариадики сделаны на каком-то очень сильном макро-колдунстве, ЕМНИП

Автор: MyNameIsIgor 30.06.13, 03:11
Цитата applegame @
в ноябрьском вариадики сделаны на каком-то очень сильном макро-колдунстве

Лолшто? :lol: Какими такими макрухами он мне компилил
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class... T>
    struct V {};

?

Автор: Kray74 30.06.13, 05:41
Цитата MyNameIsIgor @
Цитата applegame @
в ноябрьском вариадики сделаны на каком-то очень сильном макро-колдунстве

Лолшто? :lol: Какими такими макрухами он мне компилил
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class... T>
    struct V {};

?

applegame, наверное, говорит о стандартной библиотеке. Там действительно все на макросах.

Автор: MyNameIsIgor 30.06.13, 10:42
Цитата Kray74 @
applegame, наверное, говорит о стандартной библиотеке. Там действительно все на макросах.

Он говорит про ноябрьский CTP, а там шёл только компилятор

Автор: Славян 02.09.13, 15:08
Скажите, а вот такое присваивание сильно актуально, планируется? :
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int a[10];
    ...
    a[4..6] = {12,-4,80};

Автор: niXman 02.09.13, 15:11
это делается при помощи std::tuple и/или std::tie(). зачем это вносить в язык?

Добавлено
можно закодить функцию, которая будет использоваться так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int arr[10];
    slice<from, to>(arr, 12,-4,80);

Автор: MyNameIsIgor 02.09.13, 15:13
Не, это срез, кортежем не воспроизводится... Другое дело, что срезы так легко не реализуются в языке с ручным управлением памятью, так что IMHO не нужны, ибо будут только ошибки провоцировать.

Автор: niXman 02.09.13, 15:14
или так(хотя тут не уверен):
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    slice<from, to>(arr) = {12,-4,80};


Добавлено
Цитата MyNameIsIgor @
это срез, кортежем не воспроизводится

ааа, ну да. тогда при помощи fusion::vector и fusion::tie

Автор: D_KEY 02.09.13, 15:21
Так
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    valarray<int> a(10);
    ...
    a[slice{4,3,1}] = {12,-4,80};


Правда дурацкий этот valarray.

Добавлено
Упс. Опоздал.

Хотя не, тут другое немного. Пусть будет :)

Добавлено
Цитата MyNameIsIgor @
Другое дело, что срезы так легко не реализуются в языке с ручным управлением памятью, так что IMHO не нужны, ибо будут только ошибки провоцировать.

Ну если их использовать примерно так же, как boost::tie, то никаких проблем быть не должно.

Автор: amdei 11.11.13, 02:56
А "освобождение памяти определенного размера" (для глобального delete) зачем нужно?

Только чтобы позволить аллокатору не хранить размер выделенной памяти?
Или есть другие мотивы?

В чем плюсы?
А то минус очевиден - обилие багов от несовпадения размеров памяти впри выделении и освобождении.

Автор: Славян 11.11.13, 06:23
А появится что-то типа utf32 или qchar_t ?

Добавлено
Блин, наверное правильнее utf32==dchar_t, но qchar_t краше...

Автор: Kray74 11.11.13, 06:26
Будут char16_t и char32_t.

Хотя, почему будут? В GCC и Clang уже есть, только Visual Studio, как всегда, в роли догоняющего.

Автор: Славян 11.11.13, 06:30
Не, dchar_t это как бы wchar_t, а правильнее utf32==dwchar_t, но очень не красиво...

Добавлено
Цитата Kray74 @
Хотя, почему будут? В GCC и Clang уже есть, только Visual Studio, как всегда, в роли догоняющего.
Ясно, спасибки. Просто цифры в именах неприятны, хотелось полностью буковками... :blush:

Автор: Flex Ferrum 11.11.13, 06:44
Цитата Славян @
Просто цифры в именах неприятны, хотелось полностью буковками...

Надо с собой бороться. :) Циферьки - очень правильное решение, потому что фиксируют количество бит, которыми описывается тип. А вот буковки - они, на самом деле, малоинформативны.

Автор: Kray74 11.11.13, 06:45
C буковками Вы в собственных постах запутались, а представляете, что в стандарте будет :)

Автор: Славян 11.11.13, 07:09
Цитата Kray74 @
C буковками Вы в собственных постах запутались, а представляете, что в стандарте будет
Это вы в яблочко! Но в стандарте тоже же спорят, обсуждают, а потом что-то одно принимают. Кстати, вы были правы - в MSVC 2012 ужо есть char16_t и 32. Я несколько лет назад переделал все int'ы в __int32, но потом увидел сколь это мерзко и... вернул.

Автор: JoeUser 06.01.14, 18:51
Цитата MyNameIsIgor @
Очередная показуха своей безграмотности? :facepalm:

Игорь, ты (ниче что на ты?) супер! :P
Священная война с компьютерной безграмотностью ... я то думал ты только меня одного угнетаешь на этом форуме :lool:

Антиоффтопик: в связи со своим плачевно-слабым знанием С++, не совсем понимаю всех вкусностей нового стандарта, ну если только кроме лямбд, коими я пользовался в Перле еще в 1997 году. Вобщем просьба ко всем, кому не лениво - накидайте личный Top 10 фишек нового стандарта (не C++14) в порядке убывания цены, с оооочень коротким комментарием "почему".

Плаваю, просто. Например constexpr - вообще не озознаю значимости. Ну нафик делать "константные" функци???!! :-?

Автор: Qraizer 06.01.14, 19:24
JoeUser, подними тему в холиварах.

Автор: JoeUser 06.01.14, 19:33
А смысл? Просто хотелось бы, чтобы народ высказался.
Я же указал "личный" - тут холиварить бессмысленно, у каждого разные задачи и методы программинга.

А на удаление, ИМХО, зря - так и будем о "избыточных кавычках" спорить. :(

Автор: MyNameIsIgor 06.01.14, 21:14
Цитата JoeUser @
Священная война с компьютерной безграмотностью ... я то думал ты только меня одного угнетаешь на этом форуме

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

Автор: Qraizer 07.01.14, 07:48
Цитата JoeUser @
А смысл? Просто хотелось бы, чтобы народ высказался.
Там и выскажутся. Я не вижу тематической ценности в обмене субъективными предпочтениями, получится сплошной флейм. Обмен мнениями, подкреплёнными аргументами - самый милый вид холивара.

Автор: Мяут-Настоящий 07.01.14, 07:54
Цитата Славян @
Не, dchar_t это как бы wchar_t, а правильнее utf32==dwchar_t, но очень не красиво...

Учитывая логику long long - логичный вариант - это wwchar_t.
Ну и ошибка "wwwchar_t is too wide for GCC" :D

Автор: liss 07.01.14, 10:53
Цитата JoeUser @
просьба ко всем, кому не лениво - накидайте личный Top 10 фишек нового стандарта

JoeUser, накидать можно, и не в лени дело. только самостоятельное прочтение книги куда эффективнее переписки на заборах.
а по запросам типа "constexpr motivation" можно получить исчерпывающие ответы...

Автор: D_KEY 07.01.14, 13:17
Цитата Мяут-Настоящий @
Цитата Славян @
Не, dchar_t это как бы wchar_t, а правильнее utf32==dwchar_t, но очень не красиво...

Учитывая логику long long - логичный вариант - это wwchar_t.

Почему, если wchar_t сам по себе не привязан к длине и сейчас он 32 бита скорее всего почти везде(кроме windows)?

Автор: amk 07.01.14, 14:18
Цитата D_KEY @
Почему, если wchar_t сам по себе не привязан к длине и сейчас он 32 бита скорее всего почти везде(кроме windows)?
Да и там многие компиляторы уже поддерживают 32 бита.

Автор: JoeUser 10.01.14, 18:18
Просьба поделиться линком на стандарт C++11 или самим ... нашел какой-то черновик по линку, но он двухгодичной давности. А хочется нормальный. :yes-sad:

Автор: MyNameIsIgor 10.01.14, 18:25
JoeUser, вот комитет. Сам документ - за деньги, можете заказать у ISO. Но есть ссылка на последний черновик.
Цитата JoeUser @
он двухгодичной давности

А какой давности вы хотите документ, принятый в 2011 году?

Автор: D_KEY 10.01.14, 18:27
Вот

Зачем тебе стандарт? Читай доки, статьи, книги. Да и драфта хватит тебе, в случае чего.

Автор: Славян 11.01.14, 06:52
Цитата Мяут-Настоящий @
Учитывая логику long long - логичный вариант - это wwchar_t.
Ну и ошибка "wwwchar_t is too wide for GCC" :D
Не совсем согласен: устойчивость плохая. Там хоть целое слово вписали, а вы одну буковку предлагаете - неустойчиво.
Смотрите как было красиво: "char,short,int,long"!
А стало: "__int32, long long, wchar_t" и т.п. Якобы фантазия накрылась.
Надо бы: "char, utf32, unicode" и т.д. Вот это принципиально!

Добавлено
Цитата D_KEY @
Почему, если wchar_t сам по себе не привязан к длине и сейчас он 32 бита скорее всего почти везде(кроме windows)?
Вот это да! Я думал, что wchar_t всюду 16, пока не приняли новое. А скажите, есть вариант символа и для линуха и для винды, кой 2 байта всегда? Или забор из defin'ов надо городить?

Автор: Kray74 11.01.14, 07:29
Цитата Славян @
А скажите, есть вариант символа и для линуха и для винды, кой 2 байта всегда?

char16_t

Автор: Славян 11.01.14, 07:33
Спасибки!!!

Добавлено
Цитата Kray74 @
char16_t
Хм... Однако в MS VC 2012 такое не нашлось ни в string.h ни в string. Хотя помощь что-то знает такое. Подскажите, где понадёжнее откопать определение?

Автор: Kray74 11.01.14, 07:41
Цитата Kray74 @
char16_t

Глянул в стандарт, все-таки char16_t может быть и больше 2 байт, но не меньше. Однако, сомневаюсь, что такое встретится на практике.

Автор: Славян 11.01.14, 07:59
Цитата Kray74 @
Глянул в стандарт, все-таки char16_t может быть и больше 2 байт, но не меньше.
Фантастическая жесть: количество бит въявную оговорено в записи слова, а может таковым и не оказаться!!! Копец полный.

Автор: Kray74 11.01.14, 08:03
Цитата Славян @
Хм... Однако в MS VC 2012 такое не нашлось ни в string.h ни в string. Хотя помощь что-то знает такое. Подскажите, где понадёжнее откопать определение?

В студии до сих пор не реализовано :(

Автор: Qraizer 11.01.14, 12:21
Славян, ничего жёсткого. Имеются платформы, где не все биты слова участвуют в репрезентации значения типа, и это явно учтено в Стандарте:
Цитата 3.9.1 Fundamental types
1. ... Plain char, signed char, and unsigned char are three distinct types. ... For character types, all bits of the object representation participate in the value representation. For unsigned character types, all possible bit patterns of the value representation represent numbers. These requirements do not hold for other types. ...
Отсюда и least в имени типа, используемого для репрезентации char16_t. В отличие от целочисленных типов, для которых определён диапазон значений от min до мax, для символов допустимый диапазон значений не имеет смысла, а имеет смысл способность репрезентовать символы из символьного набора.

Автор: Славян 11.01.14, 13:13
Qraizer,просто я когда вижу простое имя типа, то допускаю в мысли, что он разное кол-во мест в памяти займёт на разных системах. А когда я вижу явное указание бит/байт, то мозг автоматом это помещает в конкретное целое. Как-то так, в этом и было моё эмоциональное "жесть"... Возможно, я просто не привык к таким их стандартам...

Автор: Qraizer 11.01.14, 14:14
Ну это понятно. Cшный стереотип, где char использовался - да и до сих пор используется - в качестве крохотного целого, накладывает свой отпечаток. Не даром же в Плюсах все три типа char, signed char и unsigned char разные, потому как первый - это символы, а вторые два - те самые целые. Разумеется не по факту, а по предназначению, но тут уж программеры сами должны как-то этот стереотип перебороть. То же и с широкими символами. char16_t - это не целочисленный тип, это символ с 16-битным кодированием, его репрезентация не обязана быть 16-битной, но обязана мочь репрезентовать 16-битные символы.

Автор: Славян 11.01.14, 18:20
Цитата Qraizer @
но тут уж программеры сами должны как-то этот стереотип перебороть.
А мне кажется, что это как раз и сила "программер"ов, что нет никаких символов - всё числа. Потому все char'ы - это крохотные целые и всё. Мне вот неясно, зачем вы пытаетесь увидеть в числах нечто особенное,а? :blush:

Автор: amk 11.01.14, 20:06
Собственно, с int#_t, uint#_t та же история. Они тоже не обязаны занимать ровно указанное число бит. Единственное, что от них требуется - вмещать в себя все соответствующие значения.
Понятно, что на платформе, где минимальный адресуемый участок памяти - 32 бита, и (u)int8_t, и (u)int16_t будут занимать минимум 32 бита.

Автор: Qraizer 11.01.14, 22:00
Славян, это не сила, а глупость. Символ - не число. Ты ещё скажи, что строка и массив символов ничем не отличаются.

Автор: amdei 11.01.14, 22:39
Цитата amk @
Понятно, что на платформе, где минимальный адресуемый участок памяти - 32 бита.

Чиста для интереса: а есть такие из ныне живущих?

(но то есть понятно что на некой платформе и байт может быть не 8 бит, но есть ли такие на практике?)

Автор: niXman 11.01.14, 22:41
Цитата Qraizer @
строка и массив символов

массив байт?

строка и массив символов, думаю, таки ничем не отличается. "символ" - как бы намекает, имхо.

Автор: amk 11.01.14, 22:48
Собственно char'ы были настоящими числами в чистом C. Но там это не вызывало проблем - всё равно окончательный контроль типов в основном лежал на программисте, который решал трактовать данные как символы или как числа. Там и wchar_t часто определялся как синоним какого-то из int'ов.
В C++ работа с типами почти во всём автоматизирована, и приходится различать signed char от int8_t, а wchar_t ot int поскольку логически это совершенно разные типы.

Добавлено
Цитата amdei @
Чиста для интереса: а есть такие из ныне живущих?
Есть. Возьми любой сигнальник. Обычно в них вся адресация словами по 32 бита.
Родные фирменные компиляторы обычно существуют только для чистого C с довольно ограниченной библиотекой (да и язык может быть урезан), но сторонние компиляторы (тот же GCC) могут быть собраны для них с поддержкой всего набора языков, да и библиотека может быть побогаче.

Автор: liss 11.01.14, 22:59
строка и массив символов могут быть и одним, и совсем разным, в зависимости от выбранного подхода

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

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

:off
проникая в тайны материи удобно все сущее представлять в виде молекул, атомов, полей.
а при проектировании дома удобнее размышлять в терминах строительных конструкций.

:off :off
вершину абстракции Qraizer приводил недавно в виде шаблона универсального решателя ;)

Автор: Qraizer 12.01.14, 03:49
Ошибаешься, niXman. Это тоже стереотип. Массив символов - это массив, который хранит символы. Массив в первую очередь контейнер, хранящий элементы одного типа - в частности char или там char16_t итп - последовательно без перекрытий и пропусков. Строка по определению хранит только символы и ни что другое. И при этом как контейнер это отнюдь не массив. Она может быть представлена массивом, но отнюдь не обязательно.
В C не было типа строк, поэтому вместо них использовали почти исключительно массивы символов, которые на строки похожи. Т.к. строки в общем могут иметь произвольную длину, в частности определяемую в run-time, то в виду того, что динамические массивы в C нигде не хранят длину, решили строки хранить в ASCIIZ-форме, с NUL на конце, причём молчаливо предполагая, что как часть строки этот NUL использоваться не может. Не слишком ли много условностей? Этот стереотип так закрепился, что теперь мы все имеем две проблемы.
Во-первых, std::basic_string<> свободен от всех недостатков C-строк. Это не массив, не ASCIIZ и без условностей NUL. Хранит любые символы, в любом количестве, как и любой контейнер знает, сколько он их хранит... в C++98-C++03 не было даже требования хранить символы последовательно. Собственно а зачем? Есть итераторы, есть индексация, для связи с legacy-кодом дали std::basic_string<>::data() и std::basic_string<>::c_str(), обе const, ибо они отнюдь не обязаны возвращать свой сторадж, тот вообще может быть представлен как угодно, например в виде списка деков, что весьма удобно для оптимизаций операций вставки/удаления/замещения частей строк, т.е. операций, ожидаемо часто выполняющихся над строками, в отличие от массивов. И оговорили условия, при которых возвращаемый ими std::basic_string<>::const_pointer перестаёт быть валидным. Во-вторых, стереотип настолько глубоко проник во всевозможные API, что представление строк в виде массивов стало чем-то само собой разумеющемся, в результате оказалось проще вернуть в C++11 гарантию последовательности хранения символов в std::basic_string<>. Пусть даже от стереотипа можно избавиться, программа по-любому часто взаимодействует с API, где эта непрерывность требуется, а постоянно юзать std::basic_string<>::data() const напрягает.
Вот такие пироги. В заключение хочу напомнить, что непрерывность - та ну бог с ней, в других языках строки тоже зачастую непрерывны и в реализации, а не только внешне. Но строки всё-таки не массивы, а символы всё-таки не целые. И чтобы преобразовать одно в другое требуются касты, а то и вызовы RTL.

Добавлено
Цитата amk @
Там и wchar_t часто определялся как синоним какого-то из int'ов.
И это неправильно. Этот костыль - как и определение подобным образом bool - не в состоянии полностью удовлетворить требованиям Стандарта к ним. В частности будут проблемы при использовании их в качестве аргументов шаблонов или специализаций.

Добавлено
Цитата liss @
вершину абстракции Qraizer приводил недавно в виде шаблона универсального решателя ;)
Чего я делал?? :huh:

Автор: D_KEY 12.01.14, 10:27
Что строкой вы назовете, то ей и будет :) В принципе, строка - это список(в смысле АТД, а не структуры данных) символов. А все остальное - вопрос реализации в языке/библиотеке.

Автор: korvin 12.01.14, 12:00
Цитата Qraizer @
Массив в первую очередь контейнер, хранящий элементы одного типа - в частности char или там char16_t итп - последовательно без перекрытий и пропусков. Строка по определению хранит только символы и ни что другое. И при этом как контейнер это отнюдь не массив.

Тем более в utf8 например.

Автор: liss 12.01.14, 18:24
Цитата Qraizer @
шаблона универсального решателя

гм. не нашел. вроде был пост, в котором что-то вроде
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template <typename Result, typename Problem>
    Result solve (Problem args...);

Автор: Qraizer 12.01.14, 18:45
А, понял :D Ну да, прикололся.

Автор: NeoApostol 13.01.14, 07:29
А как обстоит дело в С++14 со static if ?

Автор: Kray74 13.01.14, 08:02
Цитата NeoApostol @
А как обстоит дело в С++14 со static if ?

Никак. Последнее, что я видел - это критика static if Страуструпом (PDF).

Автор: NeoApostol 13.01.14, 12:10
Цитата Kray74 @
Цитата NeoApostol @
А как обстоит дело в С++14 со static if ?

Никак. Последнее, что я видел - это критика static if Страуструпом (PDF).

А не подскажите, есть ли какая стороняя реализация этой штуки? Может в бусте?
Я пока ничего не нашел

Автор: liss 13.01.14, 15:47
Цитата NeoApostol @
есть ли какая стороняя реализация

#if
подойдет?

Добавлено
пожалуй единственное, чего нельзя сделать без static if это по сложному условию объявить глобальную переменную.
остальное решаемо шаблонами

Автор: Qraizer 13.01.14, 17:51
liss, а пример можно, когда нельзя его заменить?

Автор: NeoApostol 13.01.14, 18:37
Цитата liss @
Цитата NeoApostol @
есть ли какая стороняя реализация

#if
подойдет?

мне для просто, что посоветуете ?
Типа
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        static if(std::is_empty<T>::value || std::is_empty<U>::value){
            
        } else {
            
        }

Автор: amk 13.01.14, 19:15
Цитата Qraizer @
И это неправильно. Этот костыль - как и определение подобным образом bool - не в состоянии полностью удовлетворить требованиям Стандарта к ним. В частности будут проблемы при использовании их в качестве аргументов шаблонов или специализаций.
Откуда в чистом C шаблоны? Или перегрузка функций? Я же писал о C, где char имело считать числовым типом, поскольку за его интерпретацию в любом случае отвечал самолично программист. В фортране хорошо было, можно было указать размер числа.

Автор: liss 13.01.14, 22:00
Цитата Qraizer @
liss, а пример можно, когда нельзя его заменить?

не пользуясь препроцессором?

Автор: Qraizer 14.01.14, 02:06
Не, когда static if нельзя заменить на шаблонны.

Автор: Axis 20.01.14, 05:12
Цитата NeoApostol @
мне для просто, что посоветуете ?
Типа
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        static if(std::is_empty<T>::value || std::is_empty<U>::value){
     
        } else {
     
        }

Вызов функции с перегрузкой.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void helper(....., std::integral_constant<bool, false>){ ... }
    void helper(....., std::integral_constant<bool, true>){ ... }
     
    helper(....., std::integral_constant<bool, std::is_empty<T>::value || std::is_empty<U>::value>());

Имхо static_if в данном случае был бы действительно приятнее. И ведь это самый простой вариант использования.

Ну да, это решение в лоб, можно и другие варианты приглядеть, всё зависит от кода внутри if. Где-то можно использовать полную/частичную специализацию.

Автор: Большой 31.01.14, 13:39
Господа, а Pure implementation method declaration в стандарте есть?

Автор: D_KEY 31.01.14, 15:54
Если ты про virtual ... > 0 и virtual ... >= 0, то нет. Зато есть более привычные для пользователей других языков override и final.

Автор: Большой 04.02.14, 15:52
D_KEY Да про это, т.е концепция была но она перерасла в override and final.

Автор: Flex Ferrum 04.03.14, 09:10
Свеженькое по поддержке последних стандартов C++ (C++11/C++14) в разных компиляторах.

Автор: Мяут-Настоящий 04.03.14, 09:21
Ого, CLang уделывает GCC :)

Автор: Flex Ferrum 05.03.14, 14:24
Свеженький драфт. Не исключено, что release candidate.

Добавлено
Ну и сам стандарт (DIS).

Автор: B.V. 05.03.14, 14:37
Цитата Flex Ferrum @
Свеженькое по поддержке последних стандартов C++ (C++11/C++14) в разных компиляторах.

А где Билдеровский компилятор?

Автор: niXman 05.03.14, 14:39
Цитата B.V. @
А где Билдеровский компилятор?

там же, где и tcc?

Автор: Flex Ferrum 05.03.14, 14:40
Цитата niXman @
там же, где и tcc?

И zcc... Остался в прошлом веке... :(

Автор: B.V. 05.03.14, 14:52
В смысле? Они с 2009-й студии начали внедрять 11-й стандарт

Автор: trainer 12.03.14, 11:53
Borland же пытается прикрутить clang.

Автор: Kray74 12.03.14, 15:20
Цитата trainer @
Borland же пытается прикрутить clang.

Это для 64 бит. 32-битный компилятор у них по-прежнему свой (весело когда одна и та же программа в одной и той же среде под x64 компилится, а под x86 выдает ошибки).

Автор: Axis 17.03.14, 10:18
Цитата Kray74 @
Это для 64 бит. 32-битный компилятор у них по-прежнему свой (весело когда одна и та же программа в одной и той же среде под x64 компилится, а под x86 выдает ошибки).
Скорее из-за стриктовости clang будет выдавать заметно больше ошибок при компиляции.

Автор: Kray74 18.03.14, 13:48
Цитата Axis @
Скорее из-за стриктовости clang будет выдавать заметно больше ошибок при компиляции.

Я имел в виду ошибки из-за использования C++11, поддержка которого в clang, как не крути, лучше.

Автор: Flex Ferrum 09.04.14, 23:24
Джосаттис сегодня просто зажигал на ACCU 2014. Выступил с презой, на которой рассказывал про, эммм, big mistakes in C++11 library. Было одновременно и интересно, и грустно. Шансов отстрелить себе ноги по шею - сильно прибавилось. Очень много времени посвятил грустной истории с async (), новые варианты вызова конструкторов (с {} вместо () ) могут добавить разработчикам n-ое количество головной боли и бессонных ночей, и всё в том же духе. Собственно, вот он сам:
20140409_160309.jpg (, : 525)

И, кстати, что, Дядя Боб тоже на этой конфе?
20140409_174655.jpg (, : 508)

Автор: Axis 10.04.14, 04:27
А видео с конфы будет?

Автор: OpenGL 10.04.14, 04:30
Цитата Flex Ferrum @
Выступил с презой, на которой рассказывал про, эммм, big mistakes in C++11 library. Было одновременно и интересно, и грустно. Шансов отстрелить себе ноги по шею - сильно прибавилось.

А где можно найти более подробную информацию об этом? А то и вообще видео этого доклада?

Автор: Flex Ferrum 10.04.14, 09:15
Цитата Axis @
А видео с конфы будет?

Ну, вообще его снимали. А вот будут ли где-нибудь видео - не знаю...

Цитата OpenGL @
А где можно найти более подробную информацию об этом?

Ну, наверное, здесь :)

Автор: Flex Ferrum 11.04.14, 19:27
Peter Sommerlad рассказывает про нововведения в C++14:
user posted image

Andrew Sutton перед докладом про Concepts Lite
user posted image

Автор: D_KEY 12.04.14, 14:06
Цитата Flex Ferrum @
Concepts Lite

Так в 14 будет?

Автор: Flex Ferrum 12.04.14, 15:11
Цитата D_KEY @
Цитата Flex Ferrum @
Concepts Lite

Так в 14 будет?

Не. Вероятнее всего в 17-ом.

Автор: Flex Ferrum 12.04.14, 22:14
Alisdair Meredith (chair of library working group) рассказывает про полиморфные аллокаторы:
user posted image
(proposal for C++17)

Hubert Matthews рассказывает про то, куда катится С++:
user posted image

Detlef Vollmann рассказывает про executors для С++ (дальнейшее развитие идеи async в сторону тредпулов и т. п.)
user posted image
(proposal for C++17)

И очень полезная табличка для тех, кто использует C++11:
user posted image

Добавлено
И да. Сегодня отрелизили gcc 4.9. Теперь и у пользователей gcc есть возможность использовать полиморфные лямбды, инициализаторы в лямбдах, вывод возвращаемого значения функций и разделители в числах. Пользователи свежего clang могут, насколько я смог понять, пользоваться практически C++14-conformant-компилятором.

Автор: Flex Ferrum 06.06.14, 07:38
Является ли этот код корректным C++11-кодом?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
    using namespace std;
     
    class Base
    {
    public:
        virtual int override() {return 0;}
    };
     
    class final final : public Base
    {
    public:
        int override() override {return 1;}
    };
     
    int main() {
        final f;
        f.override();
        
        return 0;
    }

Автор: MyNameIsIgor 06.06.14, 08:59
Цитата Flex Ferrum @
Является ли этот код корректным C++11-кодом?

Да. Потому что новые ключевые слова делали контекстно-зависимыми.

Автор: ёже 07.07.14, 16:59
ппц... я еще 14 даже не успел прочитать... че их прет каждые 3 года добавлять что-то.

Автор: Kray74 08.07.14, 08:57
Чтоб не ныли, что в языке уже 10 лет нет потоков (threads) и т.п.

Автор: ёже 08.07.14, 16:58
Kray74, нафиг они там нужны? Реализация корректной работы потоков задача операционки.

Автор: Славян 08.07.14, 17:07
Цитата ёже @
Реализация корректной работы потоков задача операционки.
Да вы что!!! Ни за что! Если так отдавать ОС, то народ никогда и не начнёт писать параллельные 'коды'. Всё - программисту! Машина пока слишком тупа, чтобы понимать, что можно делать параллельно, а что - нельзя. :yes-sad:

Автор: korvin 08.07.14, 17:52
Цитата ёже @
Реализация корректной работы потоков задача операционки.

Например "софтовые" потоки обычно заметно легковесней ОС'евых. На некоторых ОС'я вообще может не быть поддержки потоков, что же теперь, конкурентность вручную реализовывать?

Цитата Славян @
Если так отдавать ОС, то народ никогда и не начнёт писать параллельные 'коды'

Параллельность и потоки не совсем одно и то же.

Автор: Славян 08.07.14, 17:59
Цитата korvin @
Параллельность и потоки не совсем одно и то же.
Согласен, но мне подумалось, что очень кратко и существенно я попал куда надо. Или не?

Автор: ёже 08.07.14, 18:07
что такое софтовые потоки? например потоки на куте не юзают что ли winapi и posix потоки? как они их в gcc реализовали?

Добавлено
что значит легковесней? планировщик гцц тоже как реализует уже?)

Автор: MyNameIsIgor 08.07.14, 18:15
Цитата ёже @
ппц... я еще 14 даже не успел прочитать... че их прет каждые 3 года добавлять что-то.

Их прёт добавлять всякие штуки для лучше производительности, для упрощения написания кода, для большей безопасности и для более богатой стандартной библиотеки.
По поводу потоков - очень важна модель памяти. Если перекладывать это всё на особенности реализации, то при кроссплатформенности может быть много особенностей - хотя бы с инициализацией статических переменных.

Автор: ёже 08.07.14, 18:18
вообщем я ничего не понимаю уже) синхронизация тоже есть?

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

Автор: MyNameIsIgor 08.07.14, 18:22
Цитата ёже @
синхронизация тоже есть?

Конечно! Как же без неё? Вообще, почти полная копия с boost.thread (кроме прерываний потоков) + atomic-типы и новая модель памяти.
http://cppreference.com

Добавлено
Цитата ёже @
лучшая безопасность - это аккуратность написания кода ) не умеешь писать качественный код, хоть заобновляйся, останешься багоделом

Багодельность и безопасность - разные вещи. Имеется ввиду безопасность на уровне языка, т.е. меньшее количество граблей. Хотя их не сильно меньше, да.

Автор: ёже 08.07.14, 18:30
ааа дык это порт буста? либу увеличили то есть? я просто ща представлял как гцц сам реализует все эти дела при компиляции. сложный бы компилятор получился)

Автор: MyNameIsIgor 08.07.14, 18:36
Цитата ёже @
ааа дык это порт буста?

Это заимствованный из boost API. Как function, shared/weak pointers и пр.
Цитата ёже @
я просто ща представлял как гцц сам реализует все эти дела при компиляции. сложный бы компилятор получился)

Эммм... Не понимаю о чём вы.

Автор: korvin 08.07.14, 18:38
Цитата ёже @
что такое софтовые потоки? ... что значит легковесней?

Например.

Цитата ёже @
например потоки на куте не юзают что ли winapi и posix потоки? как они их в gcc реализовали?

Понятия не имею. Однако наличие потоков в стандарте позволяет менять их реализацию в зависимости от разных условий, не затрагивая "пользовательский" программный код.

Добавлено
Цитата ёже @
сложный бы компилятор получился

Как будто сейчас он ппц какой простой. =)

Автор: ёже 08.07.14, 18:49
легковесней ядерных потоков не может быть. в линуксе например ядерная библиотека их реализует. а планировщик позволяет вам их переключать. посикс потоки это на скока я помню либс реализация. ее в ядро не вставляют так как толстая. поток сам по себе кусок памяти. хз почему он должен быть легковесней...

Автор: MyNameIsIgor 08.07.14, 18:54
Цитата ёже @
легковесней ядерных потоков не может быть

:lool:

Автор: ёже 08.07.14, 19:00
надо чтобы они в библиотеку еще субд вставили) россия же тоже в этом клммитете состоит по стандартизации. Чуркина на них нет)

Автор: korvin 09.07.14, 02:59
Цитата ёже @
легковесней ядерных потоков не может быть.

Лол, ну да, как же.

Добавлено
Цитата ёже @
легковесней ядерных потоков не может быть. в линуксе например ядерная библиотека их реализует. а планировщик позволяет вам их переключать. посикс потоки это на скока я помню либс реализация. ее в ядро не вставляют так как толстая. поток сам по себе кусок памяти. хз почему он должен быть легковесней...

Хотя бы задай себе такой вопрос: почему Сишные http-сервера (тот же апач например), работающие с ядерными потоками, не создают по потоку на каждое соединение, а, например Go'шный (да и Эрланговский наверняка) http-сервер на каждое соединение создает новую корутину?

Автор: ёже 09.07.14, 04:03
это ответ на вопрос про легковесность? причем тут браузеры вообще?

Добавлено
то есть хттп сервака. юзер потоки же. не система сбора данных. ответил?

Добавлено
+ безопасность ядра. про багоделов писал уже) можно на уровне и ядра такой сервер сделать. на некоторых ос так и происходит. я так и не понял суть легковесности. что это такое и чем измеряется? я не хочу разводить холивар, просто надо разобраться)

Добавлено
в моем понимании легковесность - это либо уменьшение размера кода потока (оптимизация какая-то), либо скорость переключения контекста. может вы про скорость написания программы? разъясните)

Автор: korvin 09.07.14, 08:22
Цитата ёже @
причем тут браузеры вообще?

Действительно. И почему ты о них вспомнил?

Цитата ёже @
то есть хттп сервака. юзер потоки же. не система сбора данных. ответил?

А можно по-русски и связно?

Цитата ёже @
+ безопасность ядра.

Что это?

Цитата ёже @
можно на уровне и ядра такой сервер сделать.

Чтобы падение сервера привело к падению ядра? Отличный ход.

Цитата ёже @
я так и не понял суть легковесности

Суть в легком весе.

Цитата ёже @
что это такое и чем измеряется?

Затратами на создание потоков и их синхронизацию.

Цитата ёже @
разъясните

В википедии все разъяснено.

Автор: Axis 09.07.14, 12:48
Ну что за споры. Шустрые серваки ныне работают асинхронно в одном потоке на ядро, нет переключение контекста, минимизировано взаимодействие между потоками, работает как часы и очень быстро. Да и вообще любой асинхронный ввод-вывод ныне без проблем реализуется, поддержка есть, было бы желание понять. А делать кучу потоков это ныне моветон.

Автор: Kray74 09.07.14, 14:08
Axis, а асинхронность как реализуется?

Автор: Axis 09.07.14, 14:54
Цитата Kray74 @
Axis, а асинхронность как реализуется?

В разных системах по разному, событийными библиотеками уровня ядра. epoll/kqueue/iocp
Ну и различными более высокоуровневыми: libevent, libuv, boost.asio и куча других.

Автор: shm 09.07.14, 17:37
Цитата Kray74 @
а асинхронность как реализуется?

Внутри драйверов ОС наиболее эффективно на базе прерываний, обработчик устанавливает соответствующее событие.

Автор: korvin 09.07.14, 17:47
Цитата Axis @
А делать кучу потоков это ныне моветон.

Потоки потокам рознь. Erlang с его "зелеными" процессами рвет этот ваш асинхронный Node.JS как тузик грелку.

Автор: D_KEY 09.07.14, 17:49
Цитата Axis @
Цитата Kray74 @
Axis, а асинхронность как реализуется?

В разных системах по разному, событийными библиотеками уровня ядра. epoll/kqueue/iocp
Ну и различными более высокоуровневыми: libevent, libuv, boost.asio и куча других.

epoll и kqueue - это синхронные операции. Внезапно.

Автор: MyNameIsIgor 09.07.14, 17:54
Цитата D_KEY @
epoll и kqueue - это синхронные операции

Блокирующие, но не синхронные ;) В том смысле, что они блокируют поток управления, но они не требуются для осуществления самого ввода-вывода, а служат для демультиплексирования.

Автор: D_KEY 09.07.14, 18:10
Цитата MyNameIsIgor @
Цитата D_KEY @
epoll и kqueue - это синхронные операции

Блокирующиие, но не синхронные ;) В том смыле, что они блокиркют поток управления, но они не требуются для осуществления самого ввода-вывода, а служат для мультиплексирования.

Что там асинхронного, если ты сам опрашиваешь?

Автор: MyNameIsIgor 09.07.14, 18:21
Цитата D_KEY @
Что там асинхронного, если ты сам опрашиваешь?

Асинхронные там собственно операции ввода-вывода, как раз из-за того, что мы ожидаем множество событий, нам лишь нужно знать в каком потоке управления мы получим уведомление о событии. По-моему, понятно изложено здесь.
Собственно, POSIX AIO - это асинхронное неблокирующее API, которое может уведомить нас через сигнал/обратный вызов без каких либо блокирующих вызовов.

Автор: D_KEY 09.07.14, 19:38
Цитата MyNameIsIgor @
Цитата D_KEY @
Что там асинхронного, если ты сам опрашиваешь?

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

Мы не получаем никаких уведомлений, мы сами опрашиваем состояния у группы объектов.

Цитата
Собственно, POSIX AIO - это асинхронное неблокирующее API, которое может уведомить нас через сигнал/обратный вызов без каких либо блокирующих вызовов.
Мы не о нем говорили.

Автор: MyNameIsIgor 09.07.14, 19:48
Цитата D_KEY @
Мы не получаем никаких уведомлений, мы сами опрашиваем состояния у группы объектов.

Как это не получаем? Именно получаем - выход из epoll_wait говорит о том, что состояние у кого-то изменилось. Выход из функции - это уведомление.
Цитата D_KEY @
Мы не о нем говорили.

Ну, не о нём, но это пример асинхронного неблокирующего API. Всякие демультиплексоры - асинхронное блокирующее.

Автор: D_KEY 09.07.14, 19:49
Цитата MyNameIsIgor @
Цитата D_KEY @
Мы не получаем никаких уведомлений, мы сами опрашиваем состояния у группы объектов.

Как это не получаем? Именно получаем - выход из epoll_wait говорит о том, что состояние у кого-то изменилось. Выход из функции - это уведомление.

Ну тогда и обычный read асинхронный, ведь из него бы тоже выходим.

Автор: MyNameIsIgor 09.07.14, 19:59
Цитата D_KEY @
Ну тогда и обычный read асинхронный, ведь из него бы тоже выходим.

Т.е. между асинхронностью и неблокируемостью нет разницы?

Автор: D_KEY 09.07.14, 20:06
Цитата MyNameIsIgor @
Цитата D_KEY @
Мы не о нем говорили.

Ну, не о нём, но это пример асинхронного неблокирующего API.

Да.

Цитата
Всякие демультиплексоры - асинхронное блокирующее.

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

Добавлено
Цитата MyNameIsIgor @
Цитата D_KEY @
Ну тогда и обычный read асинхронный, ведь из него бы тоже выходим.

Т.е. между асинхронностью и неблокируемостью нет разницы?

Есть. Может быть синхронность без блокировки. И блокировка без синхронности(блокируемся до получения уведомления).

Автор: MyNameIsIgor 09.07.14, 20:22
Цитата D_KEY @
мультиплексированным(опрашиваем готовность группы)

Боюсь, мы не опрашиваем, а дожидаемся.
Цитата D_KEY @
Есть. Может быть синхронность без блокировки. И блокировка без синхронности(блокируемся до получения уведомления).

Ну, вот я демультиплексоры назвал "блокировкой без синхронности", тебя не устроило. Как же тогда будет выглядеть синхронное без блокировки и блокировка без синхронности?

Автор: D_KEY 09.07.14, 20:33
Синхронное без блокировки - это O_NONBLOCK, блокировка без синхронности - ну, например, ручная блокировка на флажке, который устанавливаем в обработчика сигнала :crazy:
Я не понимаю, где асинхронность в select. Никаких асинхронных событий не происходит. Впрочем, очень условно можно сказать, что select как раз подходит под моё описание ожидания события, другое дело, что такая терминология ничего не привносит, а так же приводит к тому, что люди часто путают асинхронный ввод-вывод с мультиплексированным...

Автор: MyNameIsIgor 09.07.14, 20:42
Цитата D_KEY @
Впрочем, очень условно можно сказать, что select как раз подходит под моё описание ожидания события, другое дело, что такая терминология ничего не привносит, а так же приводит к тому, что люди часто путают асинхронный ввод-вывод с мультиплексированным...

Ну, ok :D

Автор: ёже 10.07.14, 03:56
korvin, прочти еще раз что я писал. я с мобилы сижу, поэтому коротко все. не хочу повторяться. ага, википедия рулит) кстати, я не на 100% ей доверяю.

Автор: MyNameIsIgor 19.08.14, 08:10
We have C++14. А вы?

Автор: Славян 27.08.14, 16:46
Наткнулся тут недавно, что в шейдерах, в GLSL, реализован оператор ^^. Означает, как и ожидалось, исключающее ИЛИ, но не бинарное, а "выражения" (подобие || и &&). В Си такой штуки не завели, а вполне могли бы. Но потом я подумал, что это бы пользовалось сверхредко. А что думаете вы, спецы и пользователи С/С++ ? :scratch:

Автор: Qraizer 27.08.14, 19:14
Зачем он нужен? Обычный != его вполне заменяет.

Автор: Славян 28.08.14, 00:18
Цитата Qraizer @
Зачем он нужен? Обычный != его вполне заменяет.
Ну так выражение "4 != 6" вернёт true, а "4^^6" вернёт false. :blush:

Автор: Qraizer 28.08.14, 01:47
Это проблема? !!4 != !!6

Автор: OpenGL 28.08.14, 05:24
Цитата Славян @
а "4^^6" вернёт false.

А как оно работает? Как-то вроде (a^b) == a + b?

Добавлено
А, он чисто для булевских типов. Тогда так, как предложил Qraizer. Но в логических выражениях я и обычным ^ пользуюсь. В общем, мое имхо - оператор не нужен :)

Автор: B.V. 28.08.14, 07:50
При переходе с VB6 мне ^^ не хватало в условиях if'а.

Автор: amk 28.08.14, 08:10
Цитата Qraizer @
Это проблема? !!4 != !!6
Можно даже немного сократить: !4 != !6
А когда нужно значение, чуть быстрее работает !4 ^ !6

Автор: Идеал 28.08.14, 08:20
А что нового в С++14 и где можно прочитать?

Автор: Kray74 28.08.14, 11:12
Например.

Автор: Axis 29.08.14, 06:53
Нда, примеры там эпичны, особенно Variable Template.
circle_area(10) на выходе получим очень точную площадь равную 300. 314 никак и не получится даже.

Ну и в принципе не понимаю, какую траву авторы стандарта курили, чтобы сделать ' разделителем в числе, чтобы убить к чертям подсветку синтаксиса в редакторах?

Автор: Kray74 29.08.14, 09:34
Цитата Axis @
Ну и в принципе не понимаю, какую траву авторы стандарта курили, чтобы сделать ' разделителем в числе, чтобы убить к чертям подсветку синтаксиса в редакторах?

А ты бы что предложил? Символ ' используется многими калькуляторами, поэтому логично использовать именно его.

Автор: Axis 29.08.14, 09:56
Цитата Kray74 @
А ты бы что предложил? Символ ' используется многими калькуляторами, поэтому логично использовать именно его.
Я бы предложил в первую очередь пробел, но думаю, что с грамматикой возникнет жестокая проблема. Поэтому уж лучше какой-нить более или менее нейтральный символ, к примеру знак подчеркивания. А учитывая тот факт, что символ ' уже имеет определенное назначение, то использовать его вводит очередную путаницу.

Автор: Алексей_Л 29.08.14, 10:15
Цитата Kray74 @
Например.

а чем отличается:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [lower = lower_bound(), upper = upper_bound() ] (int x) -> int {
      if (x<lower) return lower;
      if (x>upper) return upper;
      return x;
    };

от
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [] (int x) -> int {
      auto lower = lower_bound();
      auto upper = upper_bound();
     
      if (x<lower) return lower;
      if (x>upper) return upper;
      return x;
    };


в первом случае lower и upper - это поля объекта, во втором - локальные переменные...
не чувствую никакой разницы кроме читабельности:
в первом случае внутри лямбды - только алгоритм, а во втором - нет огромной первой строки

Автор: OpenGL 29.08.14, 11:54
А зачем этот разделитель вообще нужен?

Автор: Qraizer 29.08.14, 13:07
Цитата Axis @
circle_area(10) на выходе получим очень точную площадь равную 300. 314 никак и не получится даже.
Это типичная и отнюдь не новая проблема. std::complex<int> будет вести себя так же. Решается, если очень хочется, частичной специализацией по std::numeric_limits<T>::is_integer.
Цитата Axis @
Ну и в принципе не понимаю, какую траву авторы стандарта курили, чтобы сделать ' разделителем в числе, чтобы убить к чертям подсветку синтаксиса в редакторах?
Наверное, там не с бухты барахты выбрали разделитель. Варианты рассматривались. Этот символ не мог ранее встречаться в числовых литералах, поэтому обратная совместимость наличествует. Регулярка для синтаксических колоризаторов лишь чуть усложнится.

Добавлено
Цитата Алексей_Л @
а чем отличается:
...

Суть не в этом, это просто пример. Суть в "...allow to declare and init non-static data members for the closure object...". В своё время я был немало удивлён отсутствием этой возможности, хотя интуитивно она должна была поддерживаться.

Добавлено
OpenGL, для повышения читабельности. Компиляторам несложно, человеку приятно и удобно. Пробовал писать в программе long long литералы?

Автор: Chow 29.08.14, 13:27
Цитата Qraizer @
OpenGL, для повышения читабельности. Компиляторам несложно, человеку приятно и удобно. Пробовал писать в программе long long литералы?

Ну так мало кто, сейчас набирает код в txt-редакторе. Я к тому, что эту фичу можно было бы просто вшить в редактор в виде подсветки синтаксиса (если бы триады там посдвечивались разной степенью яркости ну или бы автоматически разделялись отступом (которого в самом тексте, естественно - нет)).

Автор: Славян 29.08.14, 13:44
Цитата Chow @
Ну так мало кто, сейчас набирает код в txt-редакторе.
Не хочу разводить тут очередной холивар :blush: , но по своему десятку знакомых скажу, что таких - много. :yes:

Автор: amk 29.08.14, 13:55
На самом деле ' в качестве разделителя триад/тетрад не так уж сильно портит алгоритмы подсветки. Во-первых, никто не заставляет его использовать, кому мешает - может спокойно обходиться без разделителя (да не так уж и часто он может пригодиться). Во-вторых, апостроф легко внести в регулярное выражение, описывающее число. Поскольку в качестве разделителя разрядов он будет встречаться только после начала числа между цифрами, с началом символьного литерала (тем более с его окончанием) его не спутаешь. Я так понимаю, он будет просто игнорироваться.

Автор: Kray74 29.08.14, 14:24
Цитата Алексей_Л @
Цитата Kray74 @
Например.

а чем отличается:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [lower = lower_bound(), upper = upper_bound() ] (int x) -> int {
      if (x<lower) return lower;
      if (x>upper) return upper;
      return x;
    };

от
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto f = [] (int x) -> int {
      auto lower = lower_bound();
      auto upper = upper_bound();
     
      if (x<lower) return lower;
      if (x>upper) return upper;
      return x;
    };


в первом случае lower и upper - это поля объекта, во втором - локальные переменные...
не чувствую никакой разницы кроме читабельности:
в первом случае внутри лямбды - только алгоритм, а во втором - нет огромной первой строки

В примере не показано, но алгоритмы (lower_bound, upper_bound) принимают параметры. Если вызывать алгоритмы внутри лямбды, она захватит эти параметры, хотя ей нужен только результат. Раньше можно было записать результат алгоритма в локальную переменную и передать его лямбде, так что улучшение не очень значительное.
ИМХО это ввели чтобы можно было перемещать переменные в лямбду по rvalue-ссылке:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    std::vector<int> v = {0,1,2,3,4};
     
    auto lambda = [v=std::move(v)]() {
        // Теперь лямбда владеет вектором.
    }

Автор: Qraizer 29.08.14, 14:29
Цитата Kray74 @
В примере не показано, но алгоритмы (lower_bound, upper_bound) принимают параметры.
Судя по всему в примере вызываются не std::алгоритмы. Как насчёт методов какого-нибудь самописного класса-контейнера, где лямбда определяется тоже в одном из его методов?

Автор: OpenGL 29.08.14, 14:33
Цитата Qraizer @
OpenGL, для повышения читабельности.

Тогда бы как в яве сделали - там можно писать 1_000_000_000. Вполне удобно получается.

Добавлено
Цитата Славян @
но по своему десятку знакомых скажу, что таких - много.

В notepad++ или аналогах - вполне может быть. В блокноте без подсветки - вряд-ли.

Автор: D_KEY 29.08.14, 14:35
Так не толко в яве, а во многих языках :)

Автор: OpenGL 29.08.14, 14:36
Ну я только про яву слышал :) А где еще?

Автор: Kray74 29.08.14, 14:39
Цитата Qraizer @
Цитата Kray74 @
В примере не показано, но алгоритмы (lower_bound, upper_bound) принимают параметры.
Судя по всему в примере вызываются не std::алгоритмы. Как насчёт методов какого-нибудь самописного класса-контейнера, где лямбда определяется тоже в одном из его методов?

Вполне возможно.

Автор: D_KEY 29.08.14, 14:42
Ну в Ruby, например. Сейчас так сходу не скажу, возможно с "много" я погорячился.

Добавлено
В C++ скорее всего _ вступит в конфликт с user defined literals.

Автор: Алексей_Л 29.08.14, 18:36
Цитата Qraizer @
Суть не в этом, это просто пример. Суть в "...allow to declare and init non-static data members for the closure object...". В своё время я был немало удивлён отсутствием этой возможности, хотя интуитивно она должна была поддерживаться.

хм, спасибо, не знал, что вообще так можно - обращаться к полям лямбды
но почему-то эти самые поля - read only:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    void fun(auto f) {
        f();
        std::cout << f.callCount;
    }
     
    int main() {
        auto lambda = [callCount = 0] () {
            ++callCount;
        };
     
        fun(lambda);
    }

ругается:
Цитата
C:\Projects\Qt\CPPConsoleTest\main.cpp:10: ошибка: increment of read-only variable 'callCount'
++callCount;
^


P.S. GCC 4.9.1

Автор: Qraizer 29.08.14, 19:40
А так?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        auto lambda = [callCount = 0] () mutable {
            ++callCount;
        };

Автор: Алексей_Л 29.08.14, 20:34
Цитата Qraizer @
А так?

заработало, спасибо
а я пытался перед именем поля mutable писать...

Автор: Flex Ferrum 16.09.14, 09:48
Похоже, в стандарте могут появиться range'и вместе с ленивыми списками вычислениями: https://github.com/ericniebler/range-v3/blo...ii-introduction

Автор: Mr.Delphist 22.09.14, 19:27
Неужели Александреску со своим D вдохновил Комитет?

Автор: applegame 26.09.14, 14:39
Слайды Страуструпа о C++14/17 - https://parasol.tamu.edu/people/bs/622-GP/C++14TAMU.pdf
На последнем слайде обруган static if.

Автор: Kray74 26.09.14, 15:07
static if Страуструпом уже давно обруган.

Автор: Flex Ferrum 13.10.14, 08:59
Я просто оставлю это здесь:
operator .() от Бьерна Страуструпа.
Call syntax: x.f(y) vs. f(x,y) от Бьерна Страуструпа
Unified Call Syntax от Герба Саттера

От комментариев пока мест воздержусь... Перевариваю...

Автор: MyNameIsIgor 13.10.14, 09:15
Мля... Где концепты, мультиметоды и контракты? :facepalm:

Автор: Flex Ferrum 13.10.14, 09:21
MyNameIsIgor, концепты в работе. На счёт мультиметодов и контрактов - не в курсе.

Автор: MyNameIsIgor 13.10.14, 09:28
Цитата Flex Ferrum @
На счёт мультиметодов и контрактов - не в курсе.

По ним предложения были еще до 11 Стандарта, с тех пор всё это почило под тяжестью "неотложных" проблем языка типа range'ей.

Автор: Qraizer 13.10.14, 13:18
Цитата Flex Ferrum @
Перевариваю...
Та нечего тут переваривать. C++14 нифига не новый Стандарт. Это будет кулёчек сахара а-ля "спасибо, что выбрали наш язык в 11-м году, вот ваш бонус". В некоторых местах сахарок сомнительного качества, причём.

Автор: Flex Ferrum 13.10.14, 13:22
Qraizer, спасибо, адмирал. :)

Автор: MyNameIsIgor 13.10.14, 13:44
Qraizer, так это же не к 14 году предложения, а к 17 ;) А 14 уже утвердили :yes:

Автор: applegame 13.10.14, 18:59
Цитата Flex Ferrum @
Call syntax: x.f(y) vs. f(x,y) от Бьерна Страуструпа
Unified Call Syntax от Герба Саттера
Аха, в D UFCS уже несколько лет, и этот сахар, на самом деле, высшего качества. Правда в отличие от C++ в D не обязательно объявлять функцию до ее вызова, так что возможно, что в C++ этот сахар будет горьковатым.

Автор: Qraizer 13.10.14, 21:26
Весь этот сахар нафик не упал, applegame. Чему он действительно способствует, так это безалаберности. Но никак не профиту, хоть в малой степени соразмерному усилий в реализации. Перегрузка точки вообще маразматичная идея.

Автор: applegame 14.10.14, 05:42
Цитата Qraizer @
Весь этот сахар нафик не упал, applegame. Чему он действительно способствует, так это безалаберности.
А ты откуда знаешь? Есть опыт использования? На самом деле профит есть и не малый. Особенно хорошо получается для всяких алгоритмов:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto result = arr.find(needle).map!(e => foo(e));

вместо
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    auto result = map!(e => foo(e))(find(arr, needle));

Впрочем это D, для C++ такие фокусы не прокатят из-за отсутствия range. Но вроде их тоже собираются вводить :).
Соглашусь только в том, что лучше бы они направили свои усилия на другие направления.
Цитата Qraizer @
Перегрузка точки вообще маразматичная идея.
Значит перезагрузка -> это не маразм, а перезагрузка точки маразм?

Автор: MyNameIsIgor 14.10.14, 06:57
Вообще, к unified call syntax отношение положительное. И к переопределению точки, из-за отсутствия которого нельзя написать "идеальную ссылку", что, например, приводит к невозможности создать сложный аллокатор со своей подкачкой в оперативную память.
Но мне всё это не кажется супер важными возможностями, на которые следует тратить время, как и всякие range - их вполне могут заменить сторонние библиотеки.

Автор: D_KEY 14.10.14, 09:15
applegame, см. boost.range

Добавлено
Совершенно необязательно все пихать в стандартную библиотеку.

Автор: Flex Ferrum 14.10.14, 09:24
Цитата MyNameIsIgor @
как и всякие range - их вполне могут заменить сторонние библиотеки.

Вообще, если внимательно прочитать предложение по range'ам в стандарте - там довольно существенные изменения в концепции. Т. е. это не просто предложение добавить range'и, а попытка (в очередной раз) пересмотреть некоторые подходы к проектированию интерфейсов в STL. В частности, продвигается вариант, что begin- и end-итераторы, передаваемые в алгоритм, не обязаны быть одинакового типа. Вводится понятие терминирующих итераторов, и т. п.

Автор: Qraizer 14.10.14, 09:49
Цитата applegame @
Значит перезагрузка -> это не маразм, а перезагрузка точки маразм?
Именно. Это всё равно, что разрешить перегрузку операторов для стандартных типов.

Автор: applegame 14.10.14, 13:44
Цитата Qraizer @
Именно. Это всё равно, что разрешить перегрузку операторов для стандартных типов.
Тоже мне проблема. Вон руби-программисты живут с таким разрешением и что-то не слышно жалоб - https://ideone.com/DVVp6a

Автор: Qraizer 14.10.14, 15:31
Это не аргумент. Жить можно и не с такими косяками, живём же мы как-то с совершенно идиотским switch(). Вопрос в стоимости ошибок, которые сиими архитектурными решениями допускаются легко и непринуждённо.

Автор: D_KEY 14.10.14, 18:04
А в чем косяк у подхода в ruby?

Автор: applegame 14.10.14, 18:16
Цитата Qraizer @
Вопрос в стоимости ошибок, которые сиими архитектурными решениями допускаются легко и непринуждённо.
Точно. Легко и непринужденно, по-ошибке переопределил оператор сложения у встроенного числового типа. :D

Автор: OpenGL 15.10.14, 05:43
Цитата Qraizer @
живём же мы как-то с совершенно идиотским switch().

А что в нем идиотского? Лично я вижу разве что обязательный break в case.

Автор: Kray74 15.10.14, 05:47
Цитата applegame @
Легко и непринужденно, по-ошибке переопределил оператор сложения у встроенного числового типа.

Для встроенных типов перегружать операторы нельзя.

Автор: D_KEY 15.10.14, 06:58
Цитата Kray74 @
Цитата applegame @
Легко и непринужденно, по-ошибке переопределил оператор сложения у встроенного числового типа.

Для встроенных типов перегружать операторы нельзя.

Наверное перед ответом стоит внимательно прочесть, на что отвечаете ;)

Автор: Qraizer 15.10.14, 08:02
Цитата OpenGL @
А что в нем идиотского?
Слабонервным не открывать.

Автор: D_KEY 15.10.14, 08:38
Тогда уж что-то более классическое

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    send(to, from, count)
    register short *to, *from;
    register count;
    {
        register n = (count + 7) / 8;
        switch(count % 8) {
        case 0: do {    *to = *from++;
        case 7:     *to = *from++;
        case 6:     *to = *from++;
        case 5:     *to = *from++;
        case 4:     *to = *from++;
        case 3:     *to = *from++;
        case 2:     *to = *from++;
        case 1:     *to = *from++;
            } while(--n > 0);
        }
    }


На этой же особенности можно делать простые "сопрограммы" без стека, см. например boost.asio: stackless coroutines
boost.asio: coroutine

Автор: D_KEY 29.10.14, 19:38
Интервью Скотта Мейерса в Яндексе. О настоящем и будущем C++

Автор: Axis 30.10.14, 09:27
Цитата applegame @
Тоже мне проблема. Вон руби-программисты живут с таким разрешением и что-то не слышно жалоб - https://ideone.com/DVVp6a
А потом приходит новый разработчик и тратит совсем не чуть-чуть времени, чтобы разобраться во всей этой ахинеи.
Цитата OpenGL @
А что в нем идиотского? Лично я вижу разве что обязательный break в case.
А я не вижу обязательности break. Зато вижу проблему в обязательных { } если хочется создать переменную внутри блока case, ну и вторую проблему, что работает только с примитивными типами.

Добавлено
Цитата D_KEY @
Тогда уж что-то более классическое

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    send(to, from, count)
    register short *to, *from;
    register count;
    {
        register n = (count + 7) / 8;
        switch(count % 8) {
        case 0: do {    *to = *from++;
        case 7:     *to = *from++;
        case 6:     *to = *from++;
        case 5:     *to = *from++;
        case 4:     *to = *from++;
        case 3:     *to = *from++;
        case 2:     *to = *from++;
        case 1:     *to = *from++;
            } while(--n > 0);
        }
    }


На этой же особенности можно делать простые "сопрограммы" без стека, см. например boost.asio: stackless coroutines
boost.asio: coroutine

Очень напоминает раскрутку циклов в асме. На спектруме еще делал подобные функции для быстрого копирования памяти.

Автор: Qraizer 30.10.14, 10:41
Это вы ещё в сырцы Дума не заглядывали. Знаете, чем он занимается, когда ещё в текстовом экране точки рисует? Много точек. Строит свой код в памяти в виде кучи функций, отрисовывающих то ли спрайты, то ли текстуры в нужных масштабах, каждая в своём и каждая без переходов и условий. Просто в нужном месте вызывается нужная функция, в зависимости от нужного масштаба.

Автор: OpenGL 31.10.14, 07:14
Цитата Axis @
А я не вижу обязательности break.

Буквоед <_< Под обязательностью имелось ввиду его нужность в абсолютном большинстве случаев.

Автор: Axis 31.10.14, 07:42
Цитата Qraizer @
Это вы ещё в сырцы Дума не заглядывали. Знаете, чем он занимается, когда ещё в текстовом экране точки рисует? Много точек. Строит свой код в памяти в виде кучи функций, отрисовывающих то ли спрайты, то ли текстуры в нужных масштабах, каждая в своём и каждая без переходов и условий. Просто в нужном месте вызывается нужная функция, в зависимости от нужного масштаба.

На асме частенько генерировал код и не только такой. Но то дело было на спектруме. Сил на многое не хватало, но писал 512байт демо, по своей сути генераторы, которые забивали всю память кодом и переходили в него. Так что я совсем этому не удивляюсь ;)
Цитата OpenGL @
Буквоед Под обязательностью имелось ввиду его нужность в абсолютном большинстве случаев.

Ну и в каком процедурном языке этого не нужно?

Автор: OpenGL 31.10.14, 07:59
Цитата Axis @
Ну и в каком процедурном языке этого не нужно?

Delphi, например, прекрасно обходится без него.

Автор: Axis 31.10.14, 09:28
Цитата OpenGL @
Delphi, например, прекрасно обходится без него.
Зато там даже так не смогу написать.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int action = 0;
    switch(something)
    {
    case foo_const: action = 5;
    case bar_const: call_something(action);
    }
На кой мне как в делфи.

Автор: OpenGL 31.10.14, 09:43
Я и не говорил, что break нужен всегда. Имхо, лучше бы по-дефолту был переход в конец, а если надо идти дальше - вписывать continue.

Автор: D_KEY 31.10.14, 09:44
Цитата Axis @
Зато там даже так не смогу написать.

Какая потеря

Автор: korvin 31.10.14, 10:28
Цитата Axis @
Зато там даже так не смогу написать.

Зато в Go сможешь.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    action := 0;
    switch something {
    case foo_const:
        action = 5
        fallthrough
    case bar_const:
        call_something(action)
    }


И да, согласен с D_KEY.

Автор: applegame 04.11.14, 06:55
Цитата Axis @
Цитата applegame @
Тоже мне проблема. Вон руби-программисты живут с таким разрешением и что-то не слышно жалоб - https://ideone.com/DVVp6a
А потом приходит новый разработчик и тратит совсем не чуть-чуть времени, чтобы разобраться во всей этой ахинеи.

Это я к тому, что разрешение перезагрузки операторов для встроенных типов совсем не означает, что все бросятся их перезагружать. То бишь, в самом по себе наличии такого разрешения ничего плохого нет.

Автор: amk 04.11.14, 07:17
Цитата applegame @
Это я к тому, что разрешение перезагрузки операторов для встроенных типов совсем не означает, что все бросятся их перезагружать.
Однако на практике мы видим, что часто программист использует неудачные особенности языка (иногда доставшиеся в наследство от ранних версий) мотивируя это тем, что раз такая возможность есть, то надо её использовать (этакий фетишизм).
Цитата applegame @
То бишь, в самом по себе наличии такого разрешения ничего плохого нет.
Плохое есть в самой возможности переопределять не тобой определённое. Поскольку даже разовое использование такой возможности приведёт к тому, что объект будет по разному себя вести в зависимости от окружения. Сопровождать такой проект будет просто невозможно.

Автор: applegame 04.11.14, 08:15
Цитата amk @
Однако на практике мы видим, что часто программист использует неудачные особенности языка (иногда доставшиеся в наследство от ранних версий) мотивируя это тем, что раз такая возможность есть, то надо её использовать (этакий фетишизм).
Часто? Лично я никогда не видел чтобы кто-то на практике переопределял операторы для встроенных типов. А ты?
Цитата amk @
Плохое есть в самой возможности переопределять не тобой определённое. Поскольку даже разовое использование такой возможности приведёт к тому, что объект будет по разному себя вести в зависимости от окружения. Сопровождать такой проект будет просто невозможно.
Плохое? Это же и есть суть динамического полиморфизма. Виртуальные функции разве не переопределяют не тобой определенное?

Автор: D_KEY 04.11.14, 12:01
amk, тебя послушать, так люди на руби прям мучаются страшно... А они вполне себе живут и скорость разработки выше, чем на плюсах.

Автор: amk 04.11.14, 15:17
Цитата applegame @
Лично я никогда не видел чтобы кто-то на практике переопределял операторы для встроенных типов. А ты?
Я даже не встречал людей, пишущих на языках, позволяющих такое сделать.
Цитата applegame @
Это же и есть суть динамического полиморфизма. Виртуальные функции разве не переопределяют не тобой определенное?
Чтобы переопределить виртуальную функцию, ты определяешь новый класс, с новым поведением (хотя и не совсем новым, иначе тоже хлопот не оберёшься), а не переопределяешь поведение существующего. Ты даже можешь выяснить, какого именно класса объект тебе попался.

Цитата D_KEY @
тебя послушать, так люди на руби прям мучаются страшно... А они вполне себе живут и скорость разработки выше, чем на плюсах.
Так и я тоже на питоне пишу быстрее, чем на плюсах. При этом питон не позволяет переопределять операции для стандартных типов. Лучше бы вспомнил языки Ada или Algol W. В них ты можешь для существующих типов определять новые операции (имеющиеся при этом остаются неприкосновенными)

Автор: KILLER 15.12.14, 20:39
Цитата OpenGL @
Лично я вижу разве что обязательный break в case.

И что в break идиотского ? Напротив, дает возможность перечислять несколько условий для одного действия.

Автор: D_KEY 15.12.14, 20:53
Цитата KILLER @
Цитата OpenGL @
Лично я вижу разве что обязательный break в case.

И что в break идиотского ?

То, что его можно забыть. И при этом он нужен в большинстве типовых случаев.

Добавлено
Цитата KILLER @
Напротив, дает возможность перечислять несколько условий для одного действия.

Это можно было решить другим синтаксисом. Когда-то :)

Автор: KILLER 15.12.14, 21:06
Цитата D_KEY @
То, что его можно забыть. И при этом он нужен в большинстве типовых случаев.

Так а зачем? В чем его идиотство заключается? )

Цитата D_KEY @
Это можно было решить другим синтаксисом

Например?

Добавлено
Лишнее слово чтоль? Так лучше тогда экономить на именах переменных/методов/функций/классах ))

Автор: D_KEY 15.12.14, 21:25
Цитата KILLER @
Цитата D_KEY @
То, что его можно забыть. И при этом он нужен в большинстве типовых случаев.

Так а зачем? В чем его идиотство заключается? )

Я же говорю - его можно забыть. И подобные ошибки не так просто искать в сложных случаях. И заметь, все это на ровном месте - конструкция ведь элементарная.

Автор: KILLER 15.12.14, 21:35
Цитата D_KEY @
Я же говорю - его можно забыть. И подобные ошибки не так просто искать в сложных случаях.

В смысле отсуствие брейка ? Ну если конструкция сложная -тогда да, но ведь на это есть форматирование.

Цитата D_KEY @
И заметь, все это на ровном месте - конструкция ведь элементарная.

Ну в основном современные IDE даже генерят case вместе с break, если не генерят, тогда да - можно по затупке пропустить сей момент, но вот например точка с запятой ( ; ) после описания класса в хидере - как по мне более весомый косяк, чем тот же break. Причем я реально ловился на этом, и тратил несколько дней на поиск ошибки компиляции, ибо компилятору видимо башню сносит напрочь при отсуствии ; после объявления класса, особенно при наличии сложного наследования.

Добавлено
Блин смайл встроился, там - ; в скобках предполагалась, вместо смайла. (Я поправил ;) - Q)

Автор: Qraizer 16.12.14, 03:57
Предлагалось вместо break для большинства случаев ставить continue для меньшинства. Как бы почему бы и нет. Но с моей точки зрения это менее интуитивно, т.к. case-ы в switch() это всего лишь метки перехода, а не структурные единицы, поэтому использование break более логично для прерывания последовательности, чем continue для отсутствия прерывания. Ведь отсутствие прерывания последовательности как бы само собой подразумевается по дефолту.

Автор: OpenGL 16.12.14, 05:29
Цитата KILLER @
Так а зачем? В чем его идиотство заключается? )

В том, что он нужен почти всегда. Ведь куда менее удобно ставить почти всегда break, чем почти всегда не ставить continue. Вон korvin на прошлой странице пример из go приводил - вполне удобно же.

Автор: D_KEY 16.12.14, 06:19
Цитата OpenGL @
В том, что он нужен почти всегда. Ведь куда менее удобно ставить почти всегда break, чем почти всегда не ставить continue. Вон korvin на прошлой странице пример из go приводил - вполне удобно же.

Кстати, какой-то break при таком раскладе так же нужен. Ведь мы должны иметь возможность после continue остановиться не только в конце... Или continue/fallthrough только на один case должен опускаться?

Автор: OpenGL 16.12.14, 06:37
Цитата D_KEY @
Ведь мы должны иметь возможность после continue остановиться не только в конце

Не понял, о чём ты.
Цитата D_KEY @
Или continue/fallthrough только на один case должен опускаться?

Да, говоря о continue, я имел ввиду именно это :) А в go разве не так?

Автор: KILLER 16.12.14, 07:52
Цитата OpenGL @
В том, что он нужен почти всегда. Ведь куда менее удобно ставить почти всегда break, чем почти всегда не ставить continue.

Ну незнаю. Может я просто привык к такой конструкции, но с break мне кажется всетаки логичней.

Автор: D_KEY 16.12.14, 08:29
Цитата OpenGL @
Цитата D_KEY @
Или continue/fallthrough только на один case должен опускаться?

Да, говоря о continue, я имел ввиду именно это :) А в go разве не так?

Судя по докам - так. Но в таком случае пользоваться этим механизмом для обработки нескольких case неудобно, потребуется отдельный синтаксис.

Если в C++ когда-нибудь появится какой-то match для паттерн-матчинга(в каком-то виде), то ситуация будет лучше - старый switch останется для совместимости и трюков, а в обычных случаях можно будет юзать match.

Автор: OpenGL 16.12.14, 10:17
Цитата D_KEY @
Судя по докам - так. Но в таком случае пользоваться этим механизмом для обработки нескольких case неудобно, потребуется отдельный синтаксис.

В смысле? Чтобы
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    case 1:
    case 2:
    case 3:
        foo();

обрабатывались очевидным образом? Можно сделать, чтобы при отсутствии операторов внутри одного case автоматически переходило к следующему, как в шарпе.

Автор: D_KEY 16.12.14, 10:35
Цитата OpenGL @
Цитата D_KEY @
Судя по докам - так. Но в таком случае пользоваться этим механизмом для обработки нескольких case неудобно, потребуется отдельный синтаксис.

В смысле? Чтобы
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    case 1:
    case 2:
    case 3:
        foo();

обрабатывались очевидным образом? Можно сделать, чтобы при отсутствии операторов внутри одного case автоматически переходило к следующему

Ну так это и есть отдельный механизм. И не очень логичный, ИМХО.

Автор: applegame 19.12.14, 21:20
Сейчас будут набигать эксперты и говорить что это все говно, но мне нравится подход D:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int number;
    string message;
    switch (number)
    {
        default:    // валидно: заканчивается 'throw'
            throw new Exception("unknown number");
     
        case 3:     // валидно: заканчивается 'break' (выходит из 'switch')
            message ~= "three ";
            break;
     
        case 4:     // валидно: заканчивается 'continue' (продолжает внешний цикл)
            message ~= "four ";
            continue;
     
        case 5:     // валидно: заканчивается 'goto case' (явный переход к следующему case.)
            message ~= "five ";
            goto case;
     
        case 6:     // ошибка компиляции: неявный, потенциально ошибочный переход к следующему case
            message ~= "six ";
     
        case 1:     // валидно: пустой блок
        case 2:     // валидно: последний case в switch.
            message = "one or two";
    }

Автор: Славян 20.12.14, 05:32
Цитата applegame @
Сейчас будут набигать эксперты и говорить что это все г...
Это и не экспертами сразу видно. Подтверждаю, УГ. :yes:

Автор: applegame 20.12.14, 06:12
Цитата Славян @
Это и не экспертами сразу видно. Подтверждаю, УГ. :yes:
Таки ты игсперд!

Автор: korvin 20.12.14, 08:06
Цитата D_KEY @
Кстати, какой-то break при таком раскладе так же нужен. Ведь мы должны иметь возможность после continue остановиться не только в конце... Или continue/fallthrough только на один case должен опускаться?

Кстати break в Go позволяет выйти не только из for, но и из switch и select.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    switch foo {
    case 1:
        doWhen1()
        fallthrough
    case 2:
        doWhen1or2()
        break
    case 3:
        ...
    }


Добавлено
Цитата D_KEY @
Но в таком случае пользоваться этим механизмом для обработки нескольких case неудобно, потребуется отдельный синтаксис.

Зачем отдельный? Просто вставляешь еще один fallthrough. Полотна свичей все равно не нужны. =)

Добавлено
Цитата D_KEY @
Ну так это и есть отдельный механизм. И не очень логичный, ИМХО.

А так?

Автор: Radagast 21.12.14, 13:34
все эти неудобства в С++ специально сделаны, чтобы отучить С программистов от switch :ph34r:

Автор: Flex Ferrum 16.01.15, 13:06
user posted image

Автор: D_KEY 16.01.15, 13:29
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    { auto; }

?

Автор: B.V. 16.01.15, 14:03
Для красоты упустили return?

Автор: Relaxander 16.01.15, 15:19
про return компилятор тоже узнает

Автор: MyNameIsIgor 16.01.15, 15:26
Цитата D_KEY @
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    { auto; }

?

Т.е. не смущает, что auto не является контекстно-зависимым ключевым словом, потому им нельзя именовать сущности, да и шаблонными с помощью auto можно делать только лямбды? :)

Автор: D_KEY 17.01.15, 10:13
А нужно было перечислить все? Мне показалось наиболее интересной auto в качестве тела функции.

Автор: Mr.Delphist 17.01.15, 13:08
Ну вы блин даёте - это же функция вычисления факториала, сразу видно!

Автор: MyNameIsIgor 01.05.15, 20:16
А в пятой ветке gcc... типобезопасный printf ждёт своего создателя :whistle:

Добавлено
Хотя нет, не ждёт - невозможно :yes-sad: Грабли с функцией только времени компиляции всё ещё с нами.

Автор: Flex Ferrum 01.05.15, 20:32
Цитата MyNameIsIgor @
Грабли с функцией только времени компиляции всё ещё с нами.

Нууу... Питер Соммерленд опять выносит мозг compile-time вычислениями на C++14.
Скрытый текст
Призаюсь честно: когда слушал его вживую, к концу доклада мозг слегка закипел....

Автор: MyNameIsIgor 01.05.15, 20:40
Цитата Flex Ferrum @
Цитата MyNameIsIgor @
Грабли с функцией только времени компиляции всё ещё с нами.

Нууу... Питер Соммерленд опять выносит мозг compile-time вычислениями на C++14.
Скрытый текст
Призаюсь честно: когда слушал его вживую, к концу доклада мозг слегка закипел....

Да это всё понятно... Но я всё ещё не могу остановить компиляцию, если спецификатор в формате не совпадает с выводимым типом!
А всё потому, что внутри функции неизвестно является ли контекст константным. Это было бы известно, разреши они constexpr параметры...

Добавлено
Т.е. я о чём. Вот в коде
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    constexpr int foo(int i)
    {
        return i;
    }
     
    int main()
    {
        constexpr int i = foo(1);
        int j;
        std::cin >> j;
        int k = foo(j);
    }

нельзя сделать объявить k с модификатором constepr, потому что вызов foo не является constant expression context. И если написать printf
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class... Args>
    void printf(const char* format, Args&&... args)
    {
      size_t count = formats_count(format); // не может быть constexpr, т.к. format не является constexpr
      static_assert(count == sizeof...(Args)); // ошибка, т.к. count не constexpr
    }

А ведь прекрасно всё могло бы быть, если бы я мог написать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<class... Args>
    void printf(constexpr const char* format, Args&&... args)

Автор: Flex Ferrum 01.05.15, 21:27
Цитата MyNameIsIgor @
А ведь прекрасно всё могло бы быть, если бы я мог написать

Ну да. Соммерленд в своей презе как раз жаловался на то, что аргументы constexpr-функций нельзя лифтить в параметры шаблона...

Автор: Славян 03.05.15, 12:03
Подскажите в двух словах, что тут такого неправильного:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        #define _ПробаПера 24
что BDS XE7 ругается:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    [bcc64 Warning] Unit_1.cpp(301): ISO C99 requires whitespace after the macro name
? //Русскоязычные define'ы доступны уж давно, вроде бы... :scratch:

Добавлено
Видимо, всё же русскими буквами в C99 нельзя, раз он на латиницу перестал ругаться. Эх... :wall:

Автор: Qraizer 03.05.15, 14:35
Использование в программе символов за пределами базового символьного набора не запрещается, они входят в расширенный символьный набор, просто его состав implementation defined. Проблема может возникнуть из-за несовместимого с реализацией представления таких символов в исходном коде. Например кириллица в ANSI1251 не будет понята gcc, потому что он использует UTF-8.

Добавлено
В проблема запросто может относиться к _ в начале имени. Такие имена зарезервированы для использования реализациями в составе библиотек и не должны использоваться в программах.

Автор: Славян 03.05.15, 14:43
Цитата Qraizer @
Например кириллица в ANSI1251 не будет понята gcc, потому что он использует UTF-8.
А почему она может быть не понята, если начало - правильное (символ подчёркивания), а дальше - всё, что угодно? Не важно же, что там - кириллица или музыкальные нотки, или китайские иероглифы или ещё что-то! Непонятно. :-?

Добавлено
Цитата Qraizer @
проблема запросто может относиться к _ в начале имени. Такие имена зарезервированы для использования реализациями в составе библиотек и не должны использоваться в программах.
Здесь явно не это, т.к. при замене на _RRTT всё перестало ругаться.

Добавлено
Цитата Славян @
Не важно же, что там - кириллица или музыкальные нотки, или китайские иероглифы или ещё что-то!
А, понял! Видимо, всё же важно, ибо вот такое, скажем, будет запрещено:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #define _test[ 24
, потому компилятор перестраховывается как бы.

Автор: Qraizer 03.05.15, 16:02
Цитата Славян @
А почему она может быть не понята, если начало - правильное (символ подчёркивания), а дальше - всё, что угодно?
Не что угодно, а символ, разрешённый к использованию в идентификаторах. Если это не так, то лексический разбор текста программы будет неуспешным.

Добавлено
Вот тут это расписано более подробно.

Автор: Славян 03.05.15, 16:12
Цитата Qraizer @
Не что угодно, а символ, разрешённый к использованию в идентификаторах. Если это не так, то лексический разбор текста программы будет неуспешным.
Я уж понял, спасибо.

Автор: MyNameIsIgor 14.05.15, 10:19
Цитата MyNameIsIgor @
Но я всё ещё не могу остановить компиляцию, если спецификатор в формате не совпадает с выводимым типом!

Оказывается, могу! Только степень понятности такой остановки оставляет желать лучшего.

Сообщения были разделены в тему "Spam"

Автор: Flex Ferrum 23.04.16, 12:52
На волнах ACCU 2016 щупаю новый стандарт C++ включая готовящиеся фишки из 17-го. Ну, что хочется сказать... Язык сильно, очень сильно докрутили.
Когда-то давно я писал статью про вариадик-шаблоны в С++. И приводил пример композитора. На 14-ом стандрате этот же пример становится сильно-сильно короче:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    template<typename Op, typename ... FNs>
    struct Composer
    {
    public:
        template<typename O, typename ... Fs>
        Composer(O &&op, Fs&& ... fns)
            : m_op(std::forward<O>(op))
            , m_fns(std::make_tuple(std::forward<Fs>(fns)...))
        {
        }
        
        template<typename ... Args>
        auto operator ()(Args&& ... args)
        {
            return InvokeComposer(std::forward_as_tuple(std::forward<Args>(args)...), std::index_sequence_for<FNs ...>(), std::index_sequence_for<Args ...>());
        }
        
    private:
        template<typename Args, size_t ... FnIdxs, size_t ... ArgIdxs>
        auto InvokeComposer(Args &&args, std::index_sequence<FnIdxs...>, std::index_sequence<ArgIdxs ...>)
        {
            return m_op(Apply<ArgIdxs ...>(std::get<FnIdxs>(m_fns), std::move(args))...);
        }
                            
        template<size_t ... ArgIdxs, typename Fn, typename Args>
        auto Apply(Fn fn, Args &&args)
        {
            return fn(std::get<ArgIdxs>(std::forward<Args>(args))...);
        }
        
        Op m_op;
        std::tuple<FNs...> m_fns;
    };
     
     
    template<typename Op, typename ... FNs>
    auto MakeComposer(Op &&op, FNs&& ... fns)
    {
        return Composer<std::decay_t<Op>, std::decay_t<FNs>...>(std::forward<Op>(op), std::forward<FNs>(fns) ...);
    }


Проверял здесь.

Можно оценить, насколько код становится проще...

Автор: applegame 27.04.16, 04:39
Цитата Flex Ferrum @
вариадик-шаблоны в С++

Все ближе и ближе к D, синтаксис вот только все такой же неуклюжий.

Автор: MyNameIsIgor 05.05.16, 13:18
Цитата applegame @
Цитата Flex Ferrum @
вариадик-шаблоны в С++

Все ближе и ближе к D, синтаксис вот только все такой же неуклюжий.

Да, эти нелепые !() уже не исправить...

Автор: MyNameIsIgor 05.05.16, 17:58
http://melpon.org/wandbox/permlink/seITYiZwrdPpLYas
Ну, ни GCC 6.1, ни из репозитория не компилирует, только шланг.
Но, вообще, да: приходится использовать index_sequence и дополнительную функцию. И из-за особенностей вывода нельзя раскрыть в последовательность с использованием оператора << <_<

Автор: shm 05.05.16, 19:03
Цитата Flex Ferrum @
На 14-ом стандрате этот же пример становится сильно-сильно короче

Только читается с трудом.

Автор: Qraizer 05.05.16, 20:11
Угу. Чем дальше, тем больше метакод походит на декларативный стиль. В императивном языке это смотрится неуместно.

Автор: Flex Ferrum 05.05.16, 20:38
Цитата MyNameIsIgor @
Но, вообще, да: приходится использовать index_sequence и дополнительную функцию. И из-за особенностей вывода нельзя раскрыть в последовательность с использованием оператора <<

Да легко:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <iostream>
     
    template<typename Head, typename ... Args>
    void print(Head h, Args ... args)
    {
        std::cout << h;
        (..., (std::cout << ", " << args));
    }
     
    int main()
    {
        print('H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!', '\n');
    }

http://rextester.com/NCZCV64695

Автор: MyNameIsIgor 05.05.16, 21:15
Цитата Flex Ferrum @
Да легко

Приведённый код и код по ссылке разные. Так что я не понял: что легко то?

Добавлено
Я знаю, что можно раскрывать через operator ... operator, но в приведённом мной примере это не получится из-за противоречий в интерфейсе вывода в стандартные потоки и правил раскрытия выражения. Понятно, что эти правила придуманы так, чтобы не получить просто текстовую подстановку а-ля макросы, но вот с чем-то вроде потоков придётся выкручиваться.

Автор: Flex Ferrum 06.05.16, 06:16
MyNameIsIgor, твой и мой код эквивалентны. В смысле, приводят к одному результату. Мой при этом несколько проще.

Добавлено
Хотя, да. Вижу, чем отличаются.

Автор: Flex Ferrum 21.07.16, 14:58
Немного новостей:
https://habrahabr.ru/company/yandex/blog/30...ntent=link2post

Фишки весьма вкусные, я бы сказал.

Автор: OpenGL 21.07.16, 15:47
Цитата Flex Ferrum @
Немного новостей:

Что понимается под
Цитата
гарантированный copy elision;
?

Автор: Qraizer 21.07.16, 20:07
И никаких мультиметодов... Придётся вернуться в начало десятилетия и допилить.

Автор: Kray74 22.07.16, 04:52
Цитата OpenGL @
Цитата Flex Ferrum @
Немного новостей:

Что понимается под
Цитата
гарантированный copy elision;
?

Сейчас по стандарту компиляторы могут опускать копирование объекта в некоторых случаях, но не обязаны это делать. Вот и хотят их обязать.

Добавлено
Вот еще немного на английском.

Автор: KILLER 28.07.16, 20:12
А почему тему в свободное плавание отправили? :huh: Была же прибита к потолку.

Автор: JoeUser 28.07.16, 20:54
M

Разделил тему на две: "Новости из мира языка программирования С/C++" и эта тема

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

А в этой теме - обсуждай-не-хочу ... без холиваров в разумных пределах.

Автор: Flex Ferrum 17.03.17, 07:20
Подбивка изменений, которые ждут язык с выходом 17-го стандарта: https://github.com/tvaneerd/cpp17_in_TTs/bl...r/ALL_IN_ONE.md

Автор: OpenGL 17.03.17, 13:08
Мне одному кажется, что будет С++ не 17, а как минимум 19? :unsure:

Автор: Flex Ferrum 17.03.17, 13:17
Цитата OpenGL @
Мне одному кажется, что будет С++ не 17, а как минимум 19?

Должны вот-вот принять.

Добавлено
К слову, седьмой GCC уже все фичи нового стандарта держит. clang 4.0 - почти всё (за исключением нескольких фичей). А вот Visual Studio - традиционно в попе.

Автор: Qraizer 23.03.17, 13:58
Что-то я смотрю, совсем обленились. Количество сахара переливается через край. Нет чтоб серьёзными вещами заняться.

Автор: Mr.Delphist 24.03.17, 08:28
Цитата Qraizer @
Количество сахара переливается через край. Нет чтоб серьёзными вещами заняться.

Аналогичное ощущение про C#, кстати. Хотя на RSDN мне отдельные товарищи на голубом глазу вещают, что это невиданный прогресс и мега-фичи.

Автор: Flex Ferrum 24.03.17, 08:30
Цитата Qraizer @
Что-то я смотрю, совсем обленились. Количество сахара переливается через край. Нет чтоб серьёзными вещами заняться.

Ты знаешь, для C++ (с его историей) сахара и ещё больше можно было бы насыпать. Слишком долго всё было слишком топорно.

Автор: Qraizer 24.03.17, 11:56
Ну если серьёзных вещей не осталось, тогда пусть сластят. Но нафига мне if-init-ы и тем паче дурацкий struct-bind-инг, когда концепты по сути отклонены, а о мультиметодах даже разговора нет? Параллель-СТЛ, мать его... от я жить без него не мог. В чём была проблема разработчикам добавить прагмы OpenMP под условной компиляцией в <algorithm>? Нет, блин, надо было пропредложить, прозаседать и проапрувить. И всё ради пары сотен франков за новую копию полунового Стандарта.

Добавлено
Похоже, я приму твоё предложение, Flex Ferrum, и переведу свою тему мультиметодов. Пусть им там стыдно будет.

Автор: Flex Ferrum 24.03.17, 12:04
Цитата Qraizer @
Но нафига мне if-init-ы

Вот тебе не нужны. А мне, например, нужны. :)


Цитата Qraizer @
когда концепты по сути отклонены, а о мультиметодах даже разговора нет

С мультиметодами ты можешь вот сюда придти: http://stdcpp.ru. А концепты - да. Оттягивают конец, оттягивают.

Автор: Qraizer 25.03.17, 19:25
Ты мне предлагаешь предложение предложить, что ли? Зачем? Уже предлагали в эпоху C++0x, и воз и ныне там. Я заинтересован был в объективном сравнении своей реализации с другими.

Автор: applegame 30.07.17, 06:19
Саттеровские метаклассы.
Статическая рефлексия и макросы в плюсах?

Автор: Алексей_Л 30.07.17, 09:34
вроде прикольно
похоже на макросы в Rust

только там на входе можно работать прям с произвольной последовательностью токенов
то есть вопрос такой: будет ли предлагаемое API полностью покрывать весь синтаксис C++?
или будет решать только какое-то ограниченное подмножество задач вроде получения списка полей класса?

P.S. то что на выходе можно порождать произвольные последовательности токенов я вижу - это круто
а на входе?

Автор: Flex Ferrum 30.07.17, 09:43
Цитата applegame @
Саттеровские метаклассы.
Статическая рефлексия и макросы в плюсах?

Я на презе, где он это рассказывал, лично присутствовал. Несколько раз поймал себя на мысли: "Чувак, заткнись и возьми мои деньги!" Тут даже где в многошумовской теме от Исмаила фотки с неё есть.

Добавлено
И это не макросы. Это именно что модификация AST. AST in, AST out.

Автор: D_KEY 30.07.17, 09:48
Цитата Flex Ferrum @
И это не макросы. Это именно что модификация AST. AST in, AST out.

Ну так нормальные макросы(а не препроцессор) этим и должны заниматься.

Автор: Flex Ferrum 30.07.17, 12:43
О! Они наконец то выложили это!
https://youtu.be/6nsyX37nsRs

Автор: applegame 31.07.17, 21:11
Цитата Flex Ferrum @
И это не макросы. Это именно что модификация AST. AST in, AST out.
В нормальных современных языках это называется макросы. А в плюсах да, макросы - это препроцессор.

Автор: OpenGL 01.08.17, 06:17
Цитата Flex Ferrum @
И это не макросы. Это именно что модификация AST. AST in, AST out.

Макросы в расте - примерно то же самое :)

Автор: Qraizer 08.11.17, 19:09
Столкнулся с любопытным ограничением Стандарта. Нужно явно вызвать деструктор объекта, чей класс определён в области видимости пространства имён, отличного от текущего, и там же заtypedef-ен. Оказывается, без using этого достичь нельзя, что с моей точки зрения является дефектом Стандарта.
Конкретная задача возникла следующим образом. Потребовалось уметь создавать потоки ввода/вывода на файлах, открытыми кастомным образом посредством ОС API. Стандартных средств для этого пока нет, хотя потуги в направлении std::filesystem вроде бы наличествуют. На данный момент остаётся только пользоваться расширениями STL под конкретную платформу. Под WinAPI это к примеру некий подобный код:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        HANDLE        file;
        FILE         *fFile;
        std::filebuf  inFile
        int           handle;
     
        file = CreateFile(pat.second.c_str(), GENERIC_READ | FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL))
        if (file == INVALID_HANDLE_VALUE) /* ... */
     
        /* этот костыль нужен, т.к. создать inFile прям тут по месту невозможно: он нужен за пределами этой области видимости, поэтому создан ранее дефолтовым конструктором */
        /* можно было бы – и нужно было бы – использовать std::filebuf::open() вместо конструктора, если бы он был, однако увы, расширение STL поддерживается только конструктором */
        inFile.~filebuf();         // ошибка компиляции
        new(&inFile) std::filebuf(fFile = fdopen(handle = _open_osfhandle(reinterpret_cast<intptr_t>(file), _O_RDONLY), "rb"));
Если не использовать using std::filebuf; где-нибудь выше, то тут компилятор не находит имени filebuf, т.к. в области видимости inFile есть только полностью квалифицированное basic_filebuf<char>, а filebuf найден не будет, и любые попытки внести std:: в это выражение нарушают синтаксис явного вызова деструктора. Зато с использованием using этот самый filebuf прекрасно находится.
Кто что думает по сему поводу? Дефект али нет?

Автор: JoeUser 08.11.17, 20:52
Цитата Qraizer @
Нужно явно вызвать деструктор объекта, чей класс определён в области видимости пространства имён, отличного от текущего, и там же заtypedef-ен. Оказывается, без using этого достичь нельзя, что с моей точки зрения является дефектом Стандарта.

Покажи плс синтетический вариант. По твоему куску кода непонятно.

Автор: Flex Ferrum 08.11.17, 20:56
Присоединяюсь к комментатору выше.

Автор: Qraizer 09.11.17, 03:30
А что тут непонятного? std он везде std, std::basic_filebuf<> вполне себе стандартен и везде одинаковый, его typedef basic_filebuf<char> filebuf; известен ещё в C++98. Ну нате.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace N
    {
      struct MyClass { ~MyClass() {} };
     
      typedef MyClass A;
    }
     
    void f()
    {
      N::A a;
     
      a.~MyClass();         // имя находится, т.к. имена классов вносятся в их область видимости
      a.~A();               // имя не находится, т.к. при обработке операций . и -> (а также :: внутри скопа классов), компилятор наружу, в область видимости окаймляющего пространства имён, не выходит
      a.N::A::~A();         // был неправ, сразу не сообразил, но вот так достучаться можно...
      a.N::~A();            // ...а вот так нельзя
    }
Итак, дефект или не дефект? Прежде чем определиться с ответом, предлагаю домашнее задание: почему компилится третья строчка?

Автор: JoeUser 09.11.17, 05:05
Упрощенный вариант :lol:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    struct MyClass {};
     
    int main() {
      MyClass c;
      c.::~MyClass();        // почему не компилиться эта строчка?
      c.MyClass::~MyClass(); // а эта строчка норм
      return 0;
    }

Автор: Славян 11.03.18, 14:39
А что если в Си добавить конструкцию, чтобы стали допустимы записи вида:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #defines
     A B
     C 42
     ...
     P Q
    #enddef // или enddefs
? :unsure:
Это сократило бы исходники, и читать немножко легче стало бы... :oops:

Автор: Flex Ferrum 19.03.18, 18:38
Небольшой список вкусняшек из нового стандарта.
https://usingstdcpp.org/2018/03/18/jacksonv...impression=true

Автор: Mr.Delphist 19.03.18, 21:29
Цитата Славян @
А что если в Си добавить конструкцию, чтобы стали допустимы записи вида:

Это настолько сахар для синтаксиса, что прямо ой. Плюс не забываем про многострочные макросы с переносом строки \

Автор: amk 19.03.18, 23:57
Цитата Славян @
А что если в Си добавить конструкцию, чтобы стали допустимы записи вида:
Цитата Mr.Delphist @
Это настолько сахар для синтаксиса, что прямо ой.
Кроме того, что это ничего нового не даёт, такая запись ещё и несколько сбивает с толку - получается кусок текста, который непонятно что означает (если не видно скобок)

Автор: Славян 20.03.18, 01:22
Цитата amk @
кусок текста, который непонятно что означает (если не видно скобок)
Многострочный комментарий обладает абсолютно таким же "изъяном", - однако, он существует и успешно используется! <_<

Цитата amk @
это ничего нового не даёт
Прямо ж написано!:
Цитата Славян @
Это сократило бы исходники, и читать немножко легче стало бы...

Автор: amk 20.03.18, 17:12
Цитата Славян @
Многострочный комментарий обладает абсолютно таким же "изъяном", - однако, он существует и успешно используется!
Ну если ты в комментариях бессмыслицу пишешь, то конечно.
Цитата Славян @
Прямо ж написано!:
Добавление двух дополнительных строк текста конечно же сильно сокращает исходники.

У тебя что, каждая единица трансляции в чистом Си начинается с пары страниц макроопределений?
Да и поздно уже такое изменение вносить. Вот в году 1970-м возможно его и приняли бы.

Автор: prografix 10.09.18, 14:10
Интересно, по стандарту чему должно быть равно i в этом примере:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int i = 1;
    i = i++;

Автор: Flex Ferrum 10.09.18, 14:26
По стандарту это ill-formed и UB. Ибо двойная модификация одной переменной в рамках одного же выражения.

Автор: Wound 10.09.18, 14:28
Цитата prografix @
Интересно, по стандарту чему должно быть равно i в этом примере:

https://en.cppreference.com/w/cpp/language/eval_order

Добавлено
Цитата Flex Ferrum @
По стандарту это ill-formed и UB.

Так по старому же вроде стандарту UB, в новом точки следования убрали ведь? Или вернее заменили на что то другое.

Автор: Славян 06.04.22, 14:33
Почему бы не ввести (нововведение) такую возможность: a.1 - взятие первого бита, и т.д.? Результат - bool. ASM-овские операции bt* есть, так что можно было бы и "p.3 = 1;" писать. :scratch:

Автор: OpenGL 06.04.22, 14:43
Тогда уж взятие элементов tuple, как в rust.

Автор: Dushevny 07.04.22, 05:36
Цитата Славян @
Почему бы не ввести (нововведение) такую возможность: a.1 - взятие первого бита, и т.д.?
Потому что большие/маленькие индейцы?

Автор: Qraizer 07.04.22, 15:01
Подобные расширения есть у некоторых компиляторов для микроконтроллеров. Даже тип bit встречал. Но чтобы заСтандартизировать такое... маловостребовано это. Настолько низкий уровень нынче редкость.

Автор: Славян 07.04.22, 15:26
Ясно. Спасибо. :thanks:
Раньше, помнится, встречалось такое:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    a++;
    ...
    a++;
Т.е. выгоднее было сделать дважды добавление единицы, чем один раз a += 2; А теперь (когда и 64 бита обрабатывается за такт, и один бит) ни компиляторы, ни программисты не задумываются о таких оптимизациях. Печалька. :'(

Автор: Qraizer 07.04.22, 18:14
Сейчас соревноваться с компиляторами в оптимизации неблагодарное дело. Из мейнстримных, ясное дело, о специализированных разговор особый. К примеру
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int x, y, *array, i;
     
    /* ... */
    x += array[i++];
    y += array[i++];
компилятор запросто может превратить в
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    MOV edx, array
    MOV eax, i
    ADD x, [edx+eax*4]
    LEA eax, [eax+2*4]
    ADD y, [edx+eax*4-4]
если посчитает нужным. А почему он так посчитал, а фикъегознает. Бывает, достаточно сменить тип процессора на Atom, и уже код иначе оптимизируется. Тут нужно очень уж хорошо знать целевой процессор, тогда как обычно нам это наоборот, не хочется, а хочется, чтобы было примерно одинаково хорошо на любом.

Автор: B.V. 08.04.22, 18:38
Цитата Славян @
Почему бы не ввести (нововведение) такую возможность: a.1 - взятие первого бита, и т.д.?

А если надо группу бит? Тогда уж лучше класс STL, который будет принимать на вход любой целочисленный тип, и методом at(begin, end) выдавать нужное значение, в том же целочисленном формате

Автор: Славян 08.04.22, 19:48
Цитата B.V. @
А если надо группу бит?
Группа бит (меньшая 8 и большая, чем 1) не является базовой в x86/AMD64-архитектуре. А вот отдельный бит вполне можно считать хранящимся в каком-либо флаге регистра флагов. Так что такой низкоуровневый вариант выглядит вполне логично.
Замутки с классами и т.п. - уровень выше, а интересовала именно низкоуровневая возможность.

Автор: Qraizer 11.04.22, 13:48
Так-то в Плюсах уже давно есть std::bitset<> и std::vector<bool>. Для эстетов недавно сделали std::span<>; для бит, правда, вряд ли не подойдёт, даже если компилятор поддерживает bit.
Просто обычно незачем. Не, ну если реально нужны контейнер или масштабные битовые операции... так-то проще наоператить прямо по самому int-у старыми добрыми |, & или ^, местами с ~. Честно говоря, никогда не сетовал по поводу отсутствия прямых битовых обращений.

Автор: Славян 11.04.22, 14:48
Цитата Qraizer @
Честно говоря, никогда не сетовал по поводу отсутствия прямых битовых обращений.
Да я тоже, конечно; просто думается, что "школьники", увидевшие "a |= 64" будут понимать, что это несколько искусственное число, служащее лишь для установки такого-то бита. Посему, имей мы инструкцию "a.7 = 1", объяснения были бы естественнее.

Автор: Qraizer 11.04.22, 17:21
А почему именно a.7 = 1? Как насчёт
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    for (int i=0; i<CHAR_BIT; ++i)
      a.i = b.(CHAR_BIT-1 - i);
Может быть стоит тогда подумать об
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    bit *ptr = &a.3
Слишком много вопросов без хороших ответов.

Автор: Dushevny 12.04.22, 16:01
Цитата Славян @
просто думается, что "школьники", увидевшие "a |= 64" будут понимать, что это несколько искусственное число
Таким школьникам бью по рукам линейкой и заставляю сто раз писать на доске a |= 1 << 6. После этого у школьников появляется свободное время, которое они раньше тратили на не всегда правильные вычисления в уме ответа на вопрос "а какой же именно бит мы тут ставим?".

Автор: Славян 12.04.22, 16:26
Тут то можно, а вот как в:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if( a&64 )
? Битами было бы просто: "if( a.7 )", а сдвигами придётся ж скобки мутить!? :scratch:

Добавлено
Я конечно понимаю, что несколько нечестно выдумываю примеры, но вот так и тянет-с: "если (первый, третий, пятый и седьмой биты равны), или (4-ый и 6-й равны нулю, а второй да восьмой равны 1) то":
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if( (a.1==a.3 && a.1==a.5 && a.1==a.7) || (a.4==a.6 && a.4==0 && a.2==a.8 && a.2==0) )
На прямом способе получим-с...:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if( (!((a&(1|4|16|64))^(1|4|16|64)) || !(a&(1|4|16|64))) || (!((a&(2|128))^(2|128)) && !(a&(8|32))) )
Надеюсь, что можно написать и проще, но так уж мысля пошла... :blush:

Добавлено
Пардон, в первой строке в хвосте 1 надо:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if( (a.1==a.3 && a.1==a.5 && a.1==a.7) || (a.4==a.6 && a.4==0 && a.2==a.8 && a.2==1) )


Добавлено
Как всё это будет выглядеть со сдвигами единицы даже думать (страшно|не хочется).

Автор: Dushevny 13.04.22, 07:45
Цитата Славян @
Битами было бы просто: "if( a.7 ), а сдвигами придётся ж скобки мутить!?
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if(a & (1 << 7))

Цитата Славян @
Я конечно понимаю, что несколько нечестно выдумываю примеры, но вот так и тянет-с: "если (первый, третий, пятый и седьмой биты равны),
Ну вот разве что "если биты равны между собой". Но этот пример реально выдуманный, за 28-летнюю практику программирования микроконтроллеров (низкоуровнее некуда) хорошо если пару раз была необходимость сравнивать биты между собой, да и в те разы таких битов было всего два, поэтому можно было записать
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if(!!(a & (1 << 1)) == !!(a & (1 << 5)))


Ваш пример, соответственно, решается так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if( false
      || (!!(a & (1 << 1)) == !!(a & (1 << 3)) == !!(a & (1 << 5)) == !!(a & (1 << 7)))
      || ( true
         && !(a & (1 << 4))
         && !(a & (1 << 6))
         && (a & (1 << 2))
         && (a & (1 << 8))
         )
      )
Все-таки читаемее вашего


Но если отвлечься от придуманных примеров - то в реальных задачах каждый бит отвечает за конкретную сущность и надо именовать его этой сущностью, а не оперировать некими "магическими" числами (неважно - номерами бита или битовыми масками) и тут битовые поля вполне себе с задачей справляются:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        union shift_reg_pinout
        {
            struct
            {
                uint8_t AC_out1_red     : 1;
                uint8_t AC_out4_green   : 1;
                uint8_t AC_out4_red     : 1;
                uint8_t AC_out3_green   : 1;
                uint8_t AC_out3_red     : 1;
                uint8_t AC_out2_green   : 1;
                uint8_t AC_out2_red     : 1;
                uint8_t AC_out1_green   : 1;
     
                uint8_t AC_out5_red     : 1;
                uint8_t AC_in2_green    : 1;
                uint8_t AC_in2_red      : 1;
                uint8_t AC_in1_green    : 1;
                uint8_t AC_in1_red      : 1;
                uint8_t AC_out6_green   : 1;
                uint8_t AC_out6_red     : 1;
                uint8_t AC_out5_green   : 1;
            };
            uint16_t Raw;
        } __attribute__((packed));


А ваше желание реализуется таким же битовым полем с именами членов "_0", "_1", "_2" и т.д.

Автор: Славян 13.04.22, 09:33
Только в вашем первом коде надо поправить на 6, ибо 1<<n=2n, поэтому 1<<7 = 128.

Автор: Dushevny 13.04.22, 09:38
Цитата Славян @
Только в вашем первом коде надо поправить на 6, ибо 1<<n=2n, поэтому 1<<7 = 128.
Вы хотели проверять седьмой бит. Я его и проверил. Или вы биты считаете не с нуля, а с единицы? Тогда и все остальные надо поправлять, я привык биты считать с нуля и да, 1<<7 это 128, а 1 << 0 - это 1.

Автор: Славян 13.04.22, 14:29
Цитата Dushevny @
Или вы биты считаете не с нуля, а с единицы?
Ну в том конкретном пожелании я написал "a&64", что указывает на необходимость сдвига на 6. И запись вида a.0 несколько режет глаз, поэтому думается, что лучше бы было пользоваться видом a.1 - a.8. Вот если бы они индексировались (этап 2 :) ), как предлагал qraizer (a.i), то тогда выгоднее вести запись их с нуля. Но индексация выглядит сильно коряво, посему я о ней даже не думаю...

Автор: Dushevny 13.04.22, 16:27
Цитата Славян @
Ну в том конкретном пожелании я написал "a&64", что указывает на необходимость сдвига на 6
А, вы про тот пример? Так там я на 6 и сдвигал:
Цитата Dushevny @
Таким школьникам бью по рукам линейкой и заставляю сто раз писать на доске a |= 1 << 6.
Все, теперь понял. Я не обратил внимания на текст в блоке кода (лучше всего спрятанное лежит на самом видном месте) и начал отвечать на "if(a.7)", полагая, что вы имели ввиду седьмой бит считая с нуля. Все, мир.
Цитата Славян @
И запись вида a.0 несколько режет глаз, поэтому думается, что лучше бы было пользоваться видом a.1 - a.8
В любой документации биты нумеруются с нуля. Получается, тут все идут не в ногу и только вы один - в ногу :)

Автор: Славян 25.12.22, 16:38
Увидел, что 128-битное плавающее записывается как 'long double'.
А почему делают именно связку имеющихся типов, а не какой-то новый, скажем 'longdouble' ?
Так как-то парсер проще настроить, или ещё какие-то соображения есть? :-?

Автор: Qraizer 26.12.22, 13:04
Если коротко, то тебя обманули. В C/C++ нет чётких характеристик типов данных, есть только их характеристики относительно друг друга. (Единственное исключение – char. Его sizeof == 1, но даже для него нет требований в количестве бит.) В этом смысле long double должен быть не менее мощен, нежели double, и в частности характеристики этих типов могут совпадать.
Даже больше. Стандарты C/C++ не регламентируют представление типов с плавающей точкой. (В отличие от целочисленных, для которых какое-никакое представление регламентируется.) Они описаны в абстрактных понятиях мантиссы/порядка/знака с поведением, основанным на части IEEE-754. Другими словами, реализации не обязаны придерживаться IEEE-754 или чего-то подобного для репрезентации float/double/long double. Просто чаще всего железяки проектируют не конкретно под C/C++, а под RFS-стандарты, и следование IEEE для компоненты FPU обычно выгоднее, т.к. делает эти железяки вполне удобными безотносительно к инструментальным средствам и знакомыми программистам. Поэтому средства разработки тоже не выделываются и просто реализуют IEEE. Причём даже если исходно железяка не поддерживает плавающую точку, и среда вынуждена имитировать её наличие программными методами.
Что касается новых слов, то тут всё гораздо прозаичнее. Несложно поднастроить парсер исходного кода, наделив его знанием о новых токенах, немножечко сложнее наделить граммер знанием о характеристиках этого токена. Самое сложное – не поломать существующую кодовую базу, насчитывающую 50-летнюю историю. Когда, скажем, хренадцать лет назад писалась некая большая система, например Oracle DB, никаких bool, typeof, complex итд итп идр в языке не было, поэтому программисты вольны были использовать их в своих целях. Несложно представить, что бы произошло, если бы в C99 добавили bool с false и true. Причём имеющему влияние на всю систему целиком, независимо от того, каково было их распространение в исходном виде, пусть даже и сугубо локальное в отдельных функциях. Поэтому появление нового ключевого слова в языке всегда очень нежелательный процесс.

Автор: Majestio 26.12.22, 13:32
Цитата Qraizer @
Несложно поднастроить парсер исходного кода, наделив его знанием о новых токенах, немножечко сложнее наделить граммер знанием о характеристиках этого токена. Самое сложное – не поломать существующую кодовую базу, насчитывающую 50-летнюю историю.

Кстати, хорошая и важная тема! В этом плане С++, да и ряд еще "перпендикулярных" ЯП, типа Pascal, Rust, D и подобных - будут в жутком цейтноте переработки парсеров по мере развития стандартов. То ли дело Perl :lool: Шучу, еще и PHP. Они сделали когда-то очень, ИМХО, "знаковый" шаг - разделили понятие "переменная" и все остальное. На мой взгляд, это знатно упрощает парсинги. Я когда-то, лет 20 назад, плотно сидел на Паскале (Borland Turbo, Virtual Pascal, Delphi, Free Pascal), и спустя уже n-месяцев словил себя на мысли, да какого хрена мне писать присвоение как ":="?!! Сравнений на порядки меньше присваиваний. А потом сишные {} вместо паскалевских begin-end просто манили. Так я пришел к Перлу :lool:

Ну а если без шуток и пафоса ... если бы ввели четкое ограничение в С++ как и в PHP & Perl - именовать переменные, начиная с $ - сложность разбора, ИМХО, сильно бы просела. Повторюсь - IMHO!

Автор: Qraizer 28.12.22, 13:54
Ну, так было изначально. В Фортране, например. А потом ещё в Бейсике. Не прижилось, потому что неудобно.
К тому же не только переменными едиными. Как быть с типами, именами структур/классов/объединений, перечислениями, функциями, пространствами имён... ?

Автор: Majestio 02.01.23, 15:50
Цитата Qraizer @
К тому же не только переменными едиными. Как быть с типами, именами структур/классов/объединений, перечислениями, функциями, пространствами имён... ?

Последнее время мне приходится работать с PHP. Поверь мне, у меня есть достаточный опыт работы и с С++, и с PHP, соответственно - некоторые оправданные временем умозаключения. Даже скорее не умозаключения - а, как говорят, мышечная память, на уровне набора исходного кода. У PHP много хорошего, которое стоило бы перенять. Но есть и "шлак" в виде "персонального" обозначения видимости методов - в С++ это сделано компактнее, естественние.

Автор: Славян 05.01.23, 19:52
Нановопрос. (Давно уж спрашивал, но подзабыл ответ).
Если я пишу
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    a = *b, b++;
, то оговорено ли стандартами, что вначале всё же гарантированно будет сделана часть до запятой, а потом - то, что после запятой?
П.С. просто сие видится как "один сложный кусок в единице трансляции/интерпретации, а потому программист должен сам быть уверен, что каша в его выполнении не несёт ничего многозначного"...
:thanks:

Автор: Majestio 05.01.23, 20:16
Славян, по идее, при операции запятая сперва вычисляется левый операнд, а потом правый. В твоем случае, при таком присвоении вычисляется *b и присваивается для а, потом вычисляется b++ и отбрасывается.

А вот если бы было:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    a = (*b, ++b);

То тогда, сперва бы вычислялся операнд *b, потом инкремент b, и результат инкремента присваивался бы a. Но если бы было как написано b++, инкремент был бы строго после присвоения.

Автор: Qraizer 06.01.23, 01:21
Запятая вносит точку следования между левым и правым операндом, так что все сайд-эффекты после вычисления левого должны быть нейтрализованы. В твоём случае в , нет смысла, т.к. её приоритет ниже, чем у присваивания.

Автор: Славян 19.01.23, 18:54
Есть ли хоть какой-то шанс (хоть 1%-й), что введут в стандарт тип complex? Для комплексных чисел.
А то, мне думается, что чуть ли не 'каждый второй' ваял такой класс/методы работы с ними, но всё же (при наличии стандарта) много ж было бы несколько проще.
Или же работает принцип "есть же в бусте, значит наплюём!"?

Автор: phprus 19.01.23, 19:04
Цитата Славян @
Есть ли хоть какой-то шанс (хоть 1%-й), что введут в стандарт тип complex? Для комплексных чисел.

std::complex уже давно в стандарте.

Автор: Славян 19.01.23, 19:54
Имелось ввиду принятие его в язык Си, а не Си++.

Автор: phprus 19.01.23, 20:02
Цитата Славян @
Имелось ввиду принятие его в язык Си, а не Си++.

Тогда Complex number arithmetic из C99

Автор: Славян 22.01.23, 05:58
Цитата phprus @
Что-то почитываю, и что-то не нравятся эти намёки вида:
1. Файл corecrt_math.h
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
            struct _complex
            {
                double x, y; // real and imaginary parts
            };
     
            #if _CRT_INTERNAL_NONSTDC_NAMES && !defined __cplusplus
                // Non-ANSI name for compatibility
                #define complex _complex
            #endif
2. Файл complex.h
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #ifndef _C_COMPLEX_T
        #define _C_COMPLEX_T
        typedef struct _C_double_complex
        {
            double _Val[2];
        } _C_double_complex;
     
        typedef struct _C_float_complex
        {
            float _Val[2];
        } _C_float_complex;
     
        typedef struct _C_ldouble_complex
        {
            long double _Val[2];
        } _C_ldouble_complex;
    #endif
     
    typedef _C_double_complex  _Dcomplex;
    typedef _C_float_complex   _Fcomplex;
    typedef _C_ldouble_complex _Lcomplex;
     
     
     
    //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    //
    // Macros
    //
    //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    #define _DCOMPLEX_(re, im)  _Cbuild(re, im)
    #define _FCOMPLEX_(re, im)  _FCbuild(re, im)
    #define _LCOMPLEX_(re, im)  _LCbuild(re, im)
     
    #define _Complex_I _FCbuild(0.0F, 1.0F)
    #define I          _Complex_I
Такое ощущение, что Си-шники очередной раз всякими макросами и пр. пытаются обмануть систему. <_<

Стандарт, - это когда можно будет написать такой код:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    complex kvadrat( complex z) { return z*z; }
    // далее - что угодно
    #include <math.h>
    #include <complex.h>
    int main()
    {
      complex z=5;
      return abs(kvadrat(z)); // ну или cabs, или ещё нечто такое
    }


Добавлено
Пардон, так:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    return (int)abs(kvadrat(z)); // ну или cabs, или ещё нечто такое

Автор: Qraizer 22.01.23, 11:32
Ну, сочувствую. Это C, тут это нормально. В язык complex не введут, для встроек это крайне нерентабельно. А вот в библиотеки ввести можно, т.к. соответствующий заголовок для freestanding можно объявить необязательным. Собственно так и сделали.
Не подходит, тогда тебе в Плюсы или в Фортран.

Автор: Славян 21.10.23, 19:38
Пардон, вопрос конечно не про то, что тема ведёт, но всё же:
Какой покрохотнее компилятор посоветуете? - дабы скомпилил под Винду нечто такое:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    #include <stdio.h>
    #include <math.h>
    int
    main()
    {
      for( int i=0; i<180; i+=10)
        printf("sin(%d)=%f", i, sin(i*M_PI/180);
      return 0;
    }
Желательно под 64-бита, но желание это маленькое.

Автор: Majestio 22.10.23, 21:47
Цитата Славян @
Какой покрохотнее компилятор посоветуете? - дабы скомпилил под Винду нечто такое:

Попробуй lcc-win

Автор: Славян 23.10.23, 17:31
Попробовал. Печально. А именно:
1. Само распаковалось на 123 МБ. Мне думается, что это сильно много, ибо BorlandC где-то под 30 МБ раньше выходил и делал весьма много.
2. Просто открыть файл (с примером выше) и откомпилить не удалось - ей проект надо делать и всё такое. Минус. :no-sad:
3. При сохранении проекта, закрытии его и нажатии "открыть" прога упала. :facepalm:

Резюме: сильно попытались заморочиться, им надо было бы как-то попроще быть... :whistle:
В идеале бы: TurboC x64 (кой у меня 1,3 МБ). :rolleyes:

Автор: Majestio 24.10.23, 06:36
Цитата Славян @
1. Само распаковалось на 123 МБ. Мне думается, что это сильно много, ибо BorlandC где-то под 30 МБ раньше выходил и делал весьма много.

Ну сравнил хрен с пальцем :lol: Посмотри внимательно содержимое распакованного, там только каталог с заголовками весит 30 метров. Проект живой, под современные вёнды, потому и весит столько.

Цитата Славян @
Просто открыть файл (с примером выше) и откомпилить не удалось - ей проект надо делать и всё такое. Минус.

Минус тебе ;) Можно было бы не делать поспешных выводов, а почитать документацию! Правда юзергайд надо искать на сайте. Единственное смущает, что его сделали с инсталлятором. Тем не менее, можно компилячить и линковать без использования IDE от этого проекта, чисто его утилитами командной строки.

Цитата Славян @
При сохранении проекта, закрытии его и нажатии "открыть" прога упала.

Без комментариев :blink: У меня такое не получалось. Хотя, скажу честно, я не часто эту софтину пользую.

Цитата Славян @
Резюме: сильно попытались заморочиться, им надо было бы как-то попроще быть...

Еще раз посоветую внимательнее разобраться. Но, как говорят, если нет ... на нет и суда нет. Это не моя софтина мопед не мой, тогда да, придется тебе самому "идеал искать".

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)