Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Новый стандарт C++. C++09, Что нас ожидает... 
:(
    Опции темы
archimed7592
  Дата 12.6.2007, 13:53 (ссылка) |    (голосов:9) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



К октябрю 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


[hr]

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.

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

Код
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 хотя бы для одного из параметров берёт неконстантную ссылку, то - облом.

Код
template<class A1> void f(A1 & a1)
{
    g(a1);
}

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


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


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

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

Что же нам предлагает новый стандарт?
А предлагает он следующее: ввести новый тип ссылок - rvalue reference.
Синтаксис:
Код
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 т. е.
Код
return val; <=> return static_cast<ret_T &&>(val);

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

Forwarding problem решается теперь следующим образом:
Код
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 обеспечивается следующим образом:
Код
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, можно сделать каст, запросив необходимое поведение следующим образом:
Код
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'ом этой проблемы как правило является следующая конструкция:
Код
template < class T >
struct MyVector
{
    typedef std::vector< T, MyAllocator< T > > type;
};

MyVector< int >::type vec; // не очень красивая запись

Вторая же проблема выражается в том, что при использовании вышеобозначенного workaround'а перестаёт работать вывод шаблонных параметров.
Код
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

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

Код
template < class T >
using MyVector = std::vector< T, MyAllocator< T > >;

using MyFloat = float;

void f1(float) { }   // ok
void f1(MyFloat) { } // ill-formed - redefinition

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



[hr]

Variadic templates


Это нововведение избавляет программиста, реализующего библиотеку списков типов или библиотеку, подобную boost::bind от реализации всех возможных вариаций типа
Код
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(...);

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

Как к типам(Args), так и к экземплярам этих типов(args) можно применять разные операторы.
Код
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...:
Код
template < class... Types >
struct S
{
    enum { result = sizeof...(Types) };
};

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


[hr]

Concepts


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

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

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

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

Синтаксис концепций интуитивно понятен и поясню я только некоторые моменты.
Код
// вот так определяются концепции
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"..."). Ну а факт, я считаю, немаловажный и вполне достойный соответствующего внимания со стороны публики smile
Появились новые типы char16_t и char32_t.
Также, отдельно рассматривается добавление UTF-8(E"...").

[hr]


Initializer lists


Код
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=c#]f(new char[] {'1', 'a', '-'});[/CODE]
В С++09 предполагается нечто подобное(только без new smile).
Теперь можно будет написать
Код
std::vector< int > v = { 1, 2, 3, 4, 5 };

Как написать класс, чтобы его можно было вот так инициализировать?
Код
#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;
}




--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
S.A.G.
Дата 12.6.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


не эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1339
Регистрация: 20.7.2006
Где: in ad equate

Репутация: нет
Всего: 19



А разве Standard C++ так уж и везде реализован?

К 2009 опубликуют а кодить можно будет его применяя к 2010-2012

Это сообщение отредактировал(а) S.A.G. - 12.6.2007, 14:06


--------------------
Вот она задачка: спасти себя от себя самого © Cube
Sometimes good people do evil things © A Simple Plan
PM   Вверх
archimed7592
Дата 12.6.2007, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



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



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




Расширенная функциональность sizeof
Код
struct C
{
   some_type m;
   // ...
};

const std::size_t sz = sizeof(C::m); // C++03 - error, C++09 - ok




Delegating Constructors
Код
// 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
Код
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.
Достаточно интересная штука... настолько же, насколько и опасная, имхо...
Код
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
Код
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
Код
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
Код
std::vector<std::set<int>> v; // C++03 - ill-formed, C++09 - well-formed


Добавлено @ 14:09
Добавлено @ 14:11
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;




C99 Compatibility: __func__
Код
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 - новое ключевое слово.
Суть нововведения в том, что теперь, например, можно как размерность массива использовать результат, возвращенный ф-цией.
Код
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 array[a]; // error: ambiguous conversion




Explicit Conversion Operators
Код
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
Код
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
Код
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
Код
// новые ключевые слова: 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
Код
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
Код
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
Код
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
Код
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
Код
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;


Добавлено @ 14:14
Формальные мелочи


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 smile
В связи с отсутствием понятия 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<>


[hr]


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


cstdint из C99
Добавленна опциональная поддержка типов с размером точно соответствующим указанному.
int8_tint16_tint32_tint64_t
uint8_tuint16_tuint32_tuint64_t

Обязательная поддержка для типов с размером не меньшим указанного.
int_least8_tint_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_mapunordered_multimap,
unordered_setunordered_multiset
Вполне ожидаемые контейнеры работающие по принципу хэширования, ранее известные под названием hash_set/map в "вольных" реализациях STLport, MS VC-8.0.



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

Добавлен 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:

Добавлено через 10 минут и 23 секунды
Цитата(S.A.G. @  12.6.2007,  14:05 Найти цитируемый пост)
А разве Standard C++ так уж и везде реализован? 

Ну, по большей части - да... а даже, если нет, то комитет это не остановит от выпуска нового стандарта...
Комитет специально после 1998 first edition почти не сделал никаких новых фич, выпуская 2003 second edition, известный внутри комитета, как "service pack 1" smile, чтобы дать возможность разработчикам компиляторов успеть сделать соответствующие стандарту релизации...

Цитата(S.A.G. @  12.6.2007,  14:05 Найти цитируемый пост)
К 2009 опубликуют а кодить можно будет его применяя к 2010-2012

Нет. По идее, кодить можно будет уже в 2009 т. к. в 2007 будет выпущен final candidate document, который к 2009 почти без изменений станет новым стандартом. Специально сделано, чтобы разработчики успели сделать соответствующие стандарту реализации.



Это сообщение отредактировал(а) archimed7592 - 12.6.2007, 14:16


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 12.6.2007, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Что понравилось/долго ждали:
Цитата(archimed7592 @  12.6.2007,  13:53 Найти цитируемый пост)
Т.о. можно избежать глубокого копирования и ограничиться только лишь перемещением из возвращающей ф-ции в вызвавшую(при наличии соответствующего конструктора).

Цитата(archimed7592 @  12.6.2007,  13:53 Найти цитируемый пост)
Concepts

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Расширенная функциональность sizeof

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Delegating Constructors

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Extended friend Declarations

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Right Angle Brackets

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Defaulted and Deleted Functions

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Перегрузка операторов


Вот этого не понял...
Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Prohibited access specifier


Понял, но не поддерживаю smile
Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Pure implementation method declaration


Цитата(S.A.G. @  12.6.2007,  14:05 Найти цитируемый пост)
К 2009 опубликуют а кодить можно будет его применяя к 2010-2012

Ничего. Даже если так (хотя уже ответил archimed7592, что не совсем так), то полезность большинства фич очень и очень в плюс.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
nerezus
  Дата 12.6.2007, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 3
Всего: 43



и наконец-то в 2009 году появятся потоки...
ждем поддержку файловой системы в 2014 и сокетов в ~2049

Это сообщение отредактировал(а) nerezus - 12.6.2007, 15:12


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
JackYF
Дата 12.6.2007, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(nerezus @  12.6.2007,  15:10 Найти цитируемый пост)
и наконец-то в 2009 году появятся потоки...

boost::thread появился раньше.

Цитата(nerezus @  12.6.2007,  15:10 Найти цитируемый пост)
сокетов в ~2049

ну-ну smile



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 12.6.2007, 16:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  12.6.2007,  14:59 Найти цитируемый пост)
Prohibited access specifier

к примеру, все классы, расчитанные на динамическое использование запрещают копирование своих экземпляров
Код
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 добавили такой спецификатор доступа, который делает запрет даже ф-циям членам.
Код
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
}




Цитата(JackYF @  12.6.2007,  14:59 Найти цитируемый пост)
Понял, но не поддерживаю
Pure implementation method declaration

А зря. Это такой же синтасический сахар, как const.
Код

void f() > 0; // обязуемся реализовать метод

К тому же способствует самодокументированию кода. К примеру, собираются ввести(после С++09) preconditions, postconditions и invariants - вещи, которые нафик не нужны(как и концепции), но способствуют написанию устойчивого клиентского кода и самодокументированного библиотечного кода. Называется фича, кстати, "контрактное программирование" smile

Добавлено через 1 минуту и 7 секунд
Цитата(nerezus @  12.6.2007,  15:10 Найти цитируемый пост)
ждем поддержку файловой системы в 2014 и сокетов в ~2049

Нет. Всё это будет в TR2, который выйдет чуть позже стандарта.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 12.6.2007, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  12.6.2007,  16:11 Найти цитируемый пост)
В С++09 добавили такой спецификатор доступа, который делает запрет даже ф-циям членам.

О, теперь допер. Еще раз спасибо.



Цитата(archimed7592 @  12.6.2007,  16:11 Найти цитируемый пост)
void f() > 0; // обязуемся реализовать метод

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



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 12.6.2007, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  12.6.2007,  20:58 Найти цитируемый пост)
с этим просто граблей не было никогда, в отличие от всего остального

Классический сценарий: базовый интерфейс представляет несколько ф-ций с декларатором virtual. В производных классах эти ф-ции подменяются, но, т.к. стандарт разрешает не писать virtual в производных классах, то некоторые его не пишут(да даже если пишут - сути дела не меняет). Так вот. Кто-то очепятался и длинное имя ф-ции написал неправильно. Если стандарт кодирования принуждает писать "> 0" для переопределённых ф-ций(и этот суффикс был написан), то компилятор ругнётся. Если нет - всё скомпилится и ошибку будут искать достаточно долго.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 13.6.2007, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Если в базовом классе было прописано virtual ... (...) = 0, то в этом случае тоже компилятор ругнется. Он не сможет инстанцировать базовый абстрактный класс.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 13.6.2007, 01:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



JackYF, ну а если не было? Если базовый класс предоставляет поведение по умолчанию? как в std::basic_streambuf, к примеру, там очень уж труднопроизносимые имена ф-ций... Вот с ... (...) > 0 при неправильно записанном имени будет ошибка компиляции. Без > 0 - не будет. Удобно? Удобно. smile


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 13.6.2007, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  13.6.2007,  01:55 Найти цитируемый пост)
Без > 0 - не будет. Удобно? Удобно

Ну пускай будет smile. Мне от этого хуже точно не станет...
Станет лучше - хорошо. Не привыкнул как-то.
Блин, заканчиваю... опять повесть пишу.

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



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
bsa
Дата 13.6.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Не очень понял про alignof и alignas. 
PM   Вверх
archimed7592
Дата 13.6.2007, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(bsa @  13.6.2007,  17:52 Найти цитируемый пост)
Не очень понял про alignof и alignas.  

alignof(T) возвращает выравнивание для заданного типа.
alignas(T) или alignas(size_t const) задаёт выравнивание.
T1 alignas(T1) alignas(T2) x; - делаем выравнивание по T2, но только в том случае, если оно больше чем у T1(родного типа). Делается так потому, что на некоторых платформах выравнивание меньшее, чем родное может вызвать аппаратное исключение.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
bsa
Дата 14.6.2007, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Выравнивание - это фактическое место в памяти (расстояние между соседними объектами в байтах)?
Про исключение совсем не понял. Если T1 - какой-то класс (или тип данных), а T2 - другой класс, то запись:
Код
T1 alignas(T1) alignas(T2) x;
просто сделает выравнивание по размеру большего класса. Но тогда не понимаю, причем тут аппаратное исключение? Я так понял, оно может возникнуть:
Код
T1 alignas(T2) x;   //Если alignof(T2) < alignof(T1)
Но тогда возникает другой вопрос, а зачем надо было "обрезать" кусок данных?
Или все это нужно лишь для гарантированного размещения байта (например) в структуре без указания всяких __attribute__(pack) (или как оно)? Но тогда опять не совсем понятно, а причем тут исключение?
PM   Вверх
archimed7592
Дата 14.6.2007, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(bsa @  14.6.2007,  00:01 Найти цитируемый пост)
Выравнивание - это фактическое место в памяти (расстояние между соседними объектами в байтах)?

Цитата(bsa @  14.6.2007,  00:01 Найти цитируемый пост)
Но тогда возникает другой вопрос, а зачем надо было "обрезать" кусок данных?

Это число N. Численное представление адреса в памяти объекта типа T должно быть кратно этому числу N. Мы можем запросить как меньшее, так и большее выравнивание.


Цитата(bsa @  14.6.2007,  00:01 Найти цитируемый пост)
Или все это нужно лишь для гарантированного размещения байта (например) в структуре без указания всяких __attribute__(pack) (или как оно)?
Ага.


Цитата(bsa @  14.6.2007,  00:01 Найти цитируемый пост)
Но тогда не понимаю, причем тут аппаратное исключение?

Цитата(bsa @  14.6.2007,  00:01 Найти цитируемый пост)
Но тогда опять не совсем понятно, а причем тут исключение?

На некоторых платформах можно огрести Bus error/SIGBUS/SIGSEGV/etc в случае, если попытаться считать данные по невыровненному адресу.
Опять же, на некоторых системах это равносильно AV.
К примеру, RISC процессоры этим "страдают".
У x86 такое ограничение, ЕМНИП, только на атомарные операции(lock префикс перед операцией). Дело в том, что считывание 4-х байт по адресу некратному 4-м - операция, сбивающая процессор(любой) с толку. Просто x86 делает это очень медленно, а некоторые этого делать просто неумеют(и слава Б-гу) и генерируют аппаратное исключение(точно такое же прерывание, просто с предопределённым для него номером). Исключений, к примеру, генерируются ещё в случаях, когда процесс обращается к памяти, которая в свопе(page fault), но их обрабатывает ОС.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
bsa
Дата 14.6.2007, 00:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Так. Хорошо.
Допустим мы имеем тот самый RISC с кратностью 4. Тогда, чему равны alignof(char), alignof(short), alignof(int)? Думаю, что 4. В таком случае операция:
Код
char alignas(char) alignas(char) var;
 должна разместить var в 4-х байтах. Тогда какой толк от этого всего? Или предполагается, что я должен буду явно указывать допустимую для архитектуры размерность?
PM   Вверх
archimed7592
Дата 19.6.2007, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



bsa, у char на любых платформах выравнивание 1.

Цитата(bsa @  14.6.2007,  00:36 Найти цитируемый пост)
char alignas(char) alignas(char) var;

Не пойму, зачем так писать? То же самое, что написать
Код

char var;


Добавлено через 3 минуты и 29 секунд
Народ, если кому интересно, то вот продолжения обзора:
Стандартная библиотека C++09
Чего НЕ будет в С++09
TR1. Technical Report on C++ Library Extensions

Сюда это копипастить проблематично из-за ограничений форума на максимальную длину сообщения.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
bsa
Дата 19.6.2007, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(archimed7592 @ 19.6.2007,  19:29)
bsa, у char на любых платформах выравнивание 1.

Цитата(bsa @  14.6.2007,  00:36 Найти цитируемый пост)
char alignas(char) alignas(char) var;

Не пойму, зачем так писать? То же самое, что написать
Код

char var;


Вот именно. Тогда какой смысл в это alignof/alignas? Если можно дай пример, в котором это отображается.

Это сообщение отредактировал(а) bsa - 19.6.2007, 21:45
PM   Вверх
MAKCim
Дата 19.6.2007, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(archimed7592 @  14.6.2007,  00:16 Найти цитируемый пост)
У x86 такое ограничение, ЕМНИП, только на атомарные операции(lock префикс перед операцией).

При чем тут lock? Генерация #AC включается установкой AM в CR0 и AC в EFLAGS

Добавлено @ 22:37
Цитата(bsa @  19.6.2007,  21:45 Найти цитируемый пост)
Тогда какой смысл в это alignof/alignas? Если можно дай пример, в котором это отображается.

наверное так
Код

int alignas(int) alignas(long) a;

хотя тут можно было написать просто long a

Это сообщение отредактировал(а) MAKCim - 19.6.2007, 22:46


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 19.6.2007, 23:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(MAKCim @  19.6.2007,  22:24 Найти цитируемый пост)
При чем тут lock? Генерация #AC включается установкой AM в CR0 и AC в EFLAGS

Я давно от низкоуровнего программирования отошёл... спасибо за поправку.


Цитата(MAKCim @  19.6.2007,  22:24 Найти цитируемый пост)
наверное так
Выделить всёкод C++
1:
    
int alignas(int) alignas(long) a;

хотя тут можно было написать просто long a

Точно не знаю, но вполне возможно, что по стандарту не будет противоречить случай alignof(int) > alignof(long). Это во-первых.

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


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 20.6.2007, 08:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(archimed7592 @  19.6.2007,  23:49 Найти цитируемый пост)
Точно не знаю, но вполне возможно, что по стандарту не будет противоречить случай alignof(int) > alignof(long). Это во-первых.

хм, это будет по меньшей мере странно
сомневаюсь вообщем
Цитата(archimed7592 @  19.6.2007,  23:49 Найти цитируемый пост)
Во-вторых, намного больше применения будет наверное в шаблонном коде, где ты не знаешь заранее что за тип тебе подсунули. 

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

Добавлено через 5 минут
archimed7592
кстати, typeof() будет в новом стандарте?


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 20.6.2007, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(MAKCim @ 20.6.2007,  08:45)
archimed7592
кстати, typeof() будет в новом стандарте?

только по  другому называться будет.
Цитата
// ещё, появилась штука, ожидаемая под названием typeof.
// в C++09 её назвали decltype
decltype(container.begin()) i = container.begin();

PM   Вверх
Любитель
Дата 24.6.2007, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Во-первых, большое спасибо archimed7592 за качественную работу по переработке материала и отличный обзор smile 

Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Обсуждение упомянутых фич, а также, изложение информации о неупомянутых фичах очень даже приветствуется

Ну - как скажите smile Выскажу своё отношение ко всему этому делу.

Цитата(archimed7592 @  12.6.2007,  13:53 Найти цитируемый пост)
Variadic templates

В связи с этим хотелось бы ещё и нормальные тиипобезопасные переменные параметры функций. Поюсню примерный синтаксис и реализацию.
Код

// Объявление
void f(MyClass* ... objects)


Фактически, objects - какой-нибудь STL-контейнер: container_template<MyClass*>. Можем опционально задать container_template (в том числе и свой):
Код

void f(MyClass* ...<std::list> objects)


По умолчанию используется, например, std::vector.

При каждом конкретном вызове компилер генерит один из двух кодов:
Код

// Последовательные контейнеры
container_template<arg_type> temp_container;
temp_container.push_back(arg1);
temp_container.push_back(arg2);
// ...
function(temp_container);

// Ассоциативные контейнеры
container_template<arg_type> temp_container;
temp_container.insert(arg1);
temp_container.insert(arg2);
// ...
function(temp_container);


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

Неплохо также разрешить такой код:
Код

void f(my_class& ... objects)

При этом будет использоваться некоторый стандартный шаблон-обёртка над контейнером, с фактическим хранением указателей, и разыменованиями в нужных местах (front, back, operator [], at, итераторы).

Сам контейнер передаётся, конечно, (в любом случае) по константной ссылке.


Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
 Также, возможность выполнения атомарных операций

Хотелось бы по конкретней узнать: будут ли специальные языковые конструкции для синхронизации (типа блок операций, выполняемых одновременно лишь в одном потоке)? Очень хотелось бы.


Цитата(archimed7592 @  12.6.2007,  14:06 Найти цитируемый пост)
Strongly Typed Enums

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

using MyEnum::Val1;
using enum MyEnum;



Ещё что-то не заметил упоминания про final/sealed (как для классов, так и для методов). Тоже, нужная вещь.


<чуть позже допишу ещё>


--------------------
PM MAIL ICQ Skype   Вверх
Любитель
Дата 24.6.2007, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Ничего не заметил ещё про столь обещаемые #push, #pop - для регулирования области видимости макросов.


Ещё - когда же мы получим инклюд без препроцессора?! Чтобы нормально разруливался дабл-инклюд (без лишних макросов + директив или же тем более компилерозависимых прагм). Чтобы после хейдера, в которым кто-то забыл закрывающую фигурную скобку поставить мы не видели непонятные ошибки в каждом третьем исходнике. И пр.

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

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

Необходимость понятия сборки - также из-за желания иметь аналог internal из шарпа. Плюс его же применять к нэймспейсам (+классам, енумам и пр., хотя это не так нужно - но для симетрии).

Ещё интересно было бы увидеть (но не так, чтоб прям сильно) ООП-шные енумы, так сказать. Типо енумов в Яве или вэриантов в Немерле.

Хотелось бы услышать отношение других к моим запросам. Надеюсь, что я не один smile


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 24.6.2007, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
связи с этим хотелось бы ещё и нормальные тиипобезопасные переменные параметры функций. Поюсню примерный синтаксис и реализацию.
Выделить всёкод C++
1:
2:
    
// Объявление
void f(MyClass* ... objects)


Фактически, objects - какой-нибудь STL-контейнер: container_template<MyClass*>. Можем опционально задать container_template (в том числе и свой):
Выделить всёкод C++
1:
    
void f(MyClass* ...<std::list> objects)


По умолчанию используется, например, std::vector.

При каждом конкретном вызове компилер генерит один из двух кодов:
// Последовательные контейнеры
container_template<arg_type> temp_container;
temp_container.push_back(arg1);
temp_container.push_back(arg2);
// ...
function(temp_container);
// Ассоциативные контейнеры
container_template<arg_type> temp_container;
temp_container.insert(arg1);
temp_container.insert(arg2);
// ...
function(temp_container);


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

Неплохо также разрешить такой код:
Выделить всёкод C++
1:
    
void f(my_class& ... objects)

При этом будет использоваться некоторый стандартный шаблон-обёртка над контейнером, с фактическим хранением указателей, и разыменованиями в нужных местах (front, back, operator [], at, итераторы).

Сам контейнер передаётся, конечно, (в любом случае) по константной ссылке.


честно говоря, для меня выглядит дико как-то...



Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
Хотелось бы по конкретней узнать: будут ли специальные языковые конструкции для синхронизации (типа блок операций, выполняемых одновременно лишь в одном потоке)? Очень хотелось бы.

тут +1.

Цитата(Любитель @  24.6.2007,  11:53 Найти цитируемый пост)
Ничего не заметил ещё про столь обещаемые #push, #pop - для регулирования области видимости макросов.


Ещё - когда же мы получим инклюд без препроцессора?! Чтобы нормально разруливался дабл-инклюд (без лишних макросов + директив или же тем более компилерозависимых прагм). Чтобы после хейдера, в которым кто-то забыл закрывающую фигурную скобку поставить мы не видели непонятные ошибки в каждом третьем исходнике. И пр.

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

тут по каждому пункту тоже +1.



Цитата(Любитель @  24.6.2007,  11:53 Найти цитируемый пост)
Встаёт проблема с порядком компиляции (или как сие назвать) заголовков. Лучшем решением (не единственным, впрочем) вижу всё-таки введения понятия сборки/проекта/etc.. Встроенная минимал билд-система в некотором роде. Но в разумном виде. Можно проще поступить - задать конкретное правило полчения имени бинари-заголовка из обычного. Но это отдельно подумать надо...

Необходимость понятия сборки - также из-за желания иметь аналог internal из шарпа. Плюс его же применять к нэймспейсам (+классам, енумам и пр., хотя это не так нужно - но для симетрии).

а тут никакие стандарты уже не помогут. Слишком поздно. Раньше надо было (если вообще надо было) думать. У каждой ide своя система проектов, в Unix уже давным-давно с этим все выяснено, написано кучу утилит и программ, MS все равно плюнет на эту часть стандарта. Имхо, с этим заморачиваться просто бесполезно.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 24.6.2007, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Цитата(JackYF @  24.6.2007,  12:57 Найти цитируемый пост)
а тут никакие стандарты уже не помогут. Слишком поздно. Раньше надо было

Помогут. Если разумно делать. Я ж не говорю про всю билд систему. А минимум. Более того - необязательно хранить в одном файле, можно разрулить по ходу по параметрам команд-лайна. В яве при компайле одного класса, скажем, если надо, скомпиляться все зависимые. Однако билд-системой это вряд ли можно назвать. Билд-система - это ant. С различными правилами, задачами и пр...

Цитата(JackYF @  24.6.2007,  12:57 Найти цитируемый пост)
MS все равно плюнет на эту часть стандарта

Вряд ли. Из серьёзных билд-систем MS поддерживает на сегодня 3 (!). Мэйкфайлы, файлы проектов (они работает как из гуи студии, так и команд-лайном) и нафиг не нужный MSBUILD.

Цитата(JackYF @  24.6.2007,  12:57 Найти цитируемый пост)
честно говоря, для меня выглядит дико как-то

Почему? Тем более, с каким-нибудь boost::any - по-моему очень неплохо получается smile На сегодня многие используют возврат ссылки на самого себя из метода или оператора. Первое (скажем QString::arg) выглядит не супер, второе (например, boost::format) чуть лучше, но идеальней был бы обычный список параметров переменной длины. Просто сишные варарги в плюсах как-то не лепятся smile


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 24.6.2007, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Любитель @  24.6.2007,  13:44 Найти цитируемый пост)
Помогут. Если разумно делать. Я ж не говорю про всю билд систему. А минимум. Более того - необязательно хранить в одном файле, можно разрулить по ходу по параметрам команд-лайна. В яве при компайле одного класса, скажем, если надо, скомпиляться все зависимые. Однако билд-системой это вряд ли можно назвать. Билд-система - это ant. С различными правилами, задачами и пр...

Не верю я. Даже если сделать разумно. Никто лишний раз ради переделки под будущий стандарт не будет переделывать мэйк-файлы, билд-системы и т.д. под новый стандарт.

Цитата(Любитель @  24.6.2007,  13:44 Найти цитируемый пост)
Почему? Тем более, с каким-нибудь boost::any - по-моему очень неплохо получается smile На сегодня многие используют возврат ссылки на самого себя из метода или оператора. Первое (скажем QString::arg) выглядит не супер, второе (например, boost::format) чуть лучше, но идеальней был бы обычный список параметров переменной длины. Просто сишные варарги в плюсах как-то не лепятся smile 

для меня пока дико. Для тебя - нет. Это же все имхо.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 24.6.2007, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Цитата(JackYF @  24.6.2007,  15:57 Найти цитируемый пост)
Никто лишний раз ради переделки под будущий стандарт не будет переделывать мэйк-файлы, билд-системы и т.д. под новый стандарт

Их не надо будет переделывать.

Что нам нужно:
1. Обеспечить среду для работы internal.
2. Разруливать зависимые друг от друга заголовки.

Для первого нужно знать - "свой" данный хедйер или нет. Тупой вариант - три варианта инклюда. Например:
Код

include iostream; // инклюд стандартного заголовка
include <boost/format.hpp>; // нестандартный, но и не наш
include "my_header.hpp"; // ТОЛЬКО наш


Для второго - два варианта:
1. Иметь взаимооднозначное (но компилерозавсисимое) соответствие хейдер -- бинари-хейдер. Например: "class1.hpp" -> "class1.bhpp", "class1.h" -> "class1.bh". При нахождение инклюда и не нахождение соответствующего бинари-хейдера - тупо генерить его.
2. Передавать список хейдеров в команд-лайн. ИМХО даже хуже будет. Соответствия тяжелей задавать, лучше иметь неявные.

По-моему, всё реально.


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 24.6.2007, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Любитель @  24.6.2007,  20:34 Найти цитируемый пост)
Тупой вариант - три варианта инклюда. Например:

А чем они принципиально отличаются? кроме путей?

Насчет бинари-хедеров - я бы за... но. Дороже, сложнее и дольше выйдет, как мне кажется. Спорить особо не буду - не пробовал ;).



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Любитель
Дата 24.6.2007, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Цитата(JackYF @  24.6.2007,  22:48 Найти цитируемый пост)
А чем они принципиально отличаются? кроме путей?

Системный - это системный. Чтоб его не подменили, например. Уже полезно отделить сие будет.

А наш - он наш smile Пишем либу, юзая internal описатель. Инклюдим наш заголовок. Доступ есть. Другой проект теперь будет инклюдить как обычную либу - доступа нет. Причём, если либа комерческая, инклюдить буду лишь бинари-хейдер. Для онли бинари хейдеров разумно запретить инклюд как своих. Ибо явно не свои smile

Цитата(JackYF @  24.6.2007,  22:48 Найти цитируемый пост)
Дороже, сложнее и дольше выйдет, как мне кажется.

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


--------------------
PM MAIL ICQ Skype   Вверх
JackYF
Дата 25.6.2007, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(Любитель @  24.6.2007,  23:21 Найти цитируемый пост)
Системный - это системный. Чтоб его не подменили, например. Уже полезно отделить сие будет.

А наш - он наш smile Пишем либу, юзая internal описатель. Инклюдим наш заголовок. Доступ есть. Другой проект теперь будет инклюдить как обычную либу - доступа нет. Причём, если либа комерческая, инклюдить буду лишь бинари-хейдер. Для онли бинари хейдеров разумно запретить инклюд как своих. Ибо явно не свои smile


Не. Многовато геморроя. Да и разделение на "наши", "ваши" и "непонятно чьи" все равно будут подменять, если очень захочется. Бинарный файл заменили и - опаньки. Не, не стоит.



Цитата(Любитель @  24.6.2007,  23:21 Найти цитируемый пост)
Дык просто развить идею прекомпилед-хейдеров. gcc и vc++ точно отлично справляются с этим.

Ну... может быть. Хотя все равно не этим стандарт должен заниматься, и этим он заниматься не будет. У него (комитета) и без этого головной боли немало.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
MAKCim
Дата 25.6.2007, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(Любитель @  24.6.2007,  23:21 Найти цитируемый пост)
Системный - это системный. Чтоб его не подменили, например. Уже полезно отделить сие будет.

подменить на самом деле очень просто, неважно, системный или не системный
директория то известна


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 25.6.2007, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
В связи с этим хотелось бы ещё и нормальные тиипобезопасные переменные параметры функций. Поюсню примерный синтаксис и реализацию.

Упомянутая тобой проблема решается с помощью Variadic Templates + Concepts smile 


Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
Хотелось бы по конкретней узнать: будут ли специальные языковые конструкции для синхронизации (типа блок операций, выполняемых одновременно лишь в одном потоке)? Очень хотелось бы.

Языковых - нет. Библиотечные возможности. Вообще под атомарной операцией я имел ввиду "обменять значеними две целых переменных"(xchg - то, чего не сделаешь в текущем C++).
Атомарная операция - это никак не синхронизированный блок кода.


Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
Судя по приведённому коду, гляжу и явное включение значений енумов в текущий контекст убрали (что, безусловно, хорошо). Однако, логично было бы ещё что-то типа:

Старые enum'ы остались и вся их семантика тоже. Появились новые, более строгие. Так, что то, чего ты хочешь тоже достигается несложно smile.


Цитата(Любитель @  24.6.2007,  10:36 Найти цитируемый пост)
Ещё что-то не заметил упоминания про final/sealed (как для классов, так и для методов). Тоже, нужная вещь.
Я тоже smile. Пока упоминаний не встречал... ни в рабочем черновике, ни в отдельных документах.

Цитата(Любитель @  24.6.2007,  11:53 Найти цитируемый пост)
Ещё - когда же мы получим инклюд без препроцессора?!

Оооо... как же это я забыл smile.
В общем готовиться целая система под названием "Modules". Это будет что-то с чем-то. И скорость компиляции сильно возрастёт. И вообще всё там будет зашибись... Одна проблема: к 2009 году эта фича готова не будет. Её выпустят либо вместе с TR2, либо как отдельный TR.
Там будет всё, что ты упомянул и многое другое smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Любитель
Дата 26.6.2007, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Цитата(MAKCim @  25.6.2007,  10:53 Найти цитируемый пост)
подменить на самом деле очень просто, неважно, системный или не системныйдиректория то известна

Ну если так - то и компилер заменить можно smile Имеются ввиду подмены другим файлом (в другой папочке).

Цитата(archimed7592 @  25.6.2007,  14:45 Найти цитируемый пост)
Упомянутая тобой проблема решается с помощью Variadic Templates + Concepts

Не решается. Если я правильно понимаю, мы получим на 2 аргумента одну функцию, на три другую и т. д. Мне бы хотелось одну, но с контенйером. Здесь идеологически шаблоны не нужны. smile

Цитата(archimed7592 @  25.6.2007,  14:45 Найти цитируемый пост)
Старые enum'ы остались и вся их семантика тоже. Появились новые, более строгие. Так, что то, чего ты хочешь тоже достигается несложно

Мне бы хотелось для новых юзинг (пусть и крайне редко). Есть или нет?


--------------------
PM MAIL ICQ Skype   Вверх
Любитель
Дата 26.6.2007, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Цитата(archimed7592 @  25.6.2007,  14:45 Найти цитируемый пост)
Языковых - нет.

А жаль кстати. Хотелось бы некий аналог подобных блоков из шарпа - очень наглядно smile

Ещё хотелось бы что-то типа атрибутов из того же шарпа smile Очень красивая вещь...

Добавлено через 4 минуты и 46 секунд
Цитата(archimed7592 @  25.6.2007,  14:45 Найти цитируемый пост)
В общем готовиться целая система под названием "Modules".

Немного посмотрел. Супер. Тяжело будет правда, наверно, портировать текущий код :(


--------------------
PM MAIL ICQ Skype   Вверх
caustic
Дата 5.12.2007, 09:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 5.12.2007

Репутация: нет
Всего: нет



Доброго дня!
Я заметил, что в новом стандарте многие предпочитают видеть аналог ключевого слова sealed. На днях случайно обнаружил, что в 2005 студии такое ключевое слово есть и даже работает. Проверил таким образом:


Код

class State sealed
{
public:
    State(unsigned long id = 0);

    virtual void Load();
    virtual void Close();
};

class TestState : public State
{
};


Сообщение компилятора: 
Error     1     error C3246: 'TestState' : cannot inherit from 'State' as it has been declared as 'sealed'   

Вопрос: Это реализовано только под студией или же в других стандартах тоже имеется?

Это сообщение отредактировал(а) caustic - 5.12.2007, 09:34
PM MAIL   Вверх
archimed7592
Дата 5.12.2007, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(caustic @  5.12.2007,  09:12 Найти цитируемый пост)
Вопрос: Это реализовано только под студией или же в других стандартах тоже имеется?

Это реализованно студией в рамках поддержки managed C++. По идее она должна предупреждать, что Вы используете нестандартную возможность языка, пришедшую из .NET'а.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Loony
Дата 6.12.2007, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 6.12.2007

Репутация: нет
Всего: нет



Цитата

Это реализованно студией в рамках поддержки managed C++. По идее она должна предупреждать, что Вы используете нестандартную возможность языка, пришедшую из .NET'а.


Ничего подобного. Сам тоже щас проверял. Предупреждений не было. Проект создавался просто как Empty Project, то есть получаем после компилляции машинный код, а не .NET сборку. Значит возможность эта в студии все таки реализована. Тоже интересно, где нибудь еще поддерживается!? 
PM MAIL   Вверх
archimed7592
Дата 6.12.2007, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Loony @  6.12.2007,  08:10 Найти цитируемый пост)
Ничего подобного.

Если бы Вы читали чуть внимательней, то не делали бы таких резких утверждений.

Эта возможность в студии действительно реализована. Но реализовали её не потому что им просто так захотелось добавить возможность в язык. Реализовали её потому что она нужна была для полноценной поддержки managed C++. Ну а то, что эту возможность не запретили использовать в unmanaged C++ проектах - это уже их личное дело и никто не станет реализовывать эту возможность в других компиляторах.
Это точно такое же расширение, как, к примеру, пространства имён у перечислений.
Код

enum E { e1, e2, e3 };
E v2 = e1; // так по стандарту
E v1 = E::e1; // а так разрешает писать студия из-за того, что ей просто нужно разрешать так писать в C++/CLI.


Да, эти возможности доступны в обыкновенных проектах и я не утверждал обратного. Я говорю о причине появления этих возможностей и, соответственно, о следствиях - эти возможности не появятся в других компиляторах просто так. Strongly typed enums есть в черновике стандарта и скоро они появятся, а вот sealed - нету и, соответственно, это останется расширением студии.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Loony
Дата 6.12.2007, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 6.12.2007

Репутация: нет
Всего: нет



Цитата

Если бы Вы читали чуть внимательней, то не делали бы таких резких утверждений.


Видимо мы немного не поняли друг друга. Я извиняюсь, если прозвучало резко, лишь хотел подчеркнуть наличие этой возможности в студии и отсутствие варнингов со стороны компилятора. Я не утверждал, что студия это стандарт де-факто и все ее возможности должны поддерживать другие компиляторы!

Цитата

Ну а то, что эту возможность не запретили использовать в unmanaged C++ проектах - это уже их личное дело и никто не станет реализовывать эту возможность в других компиляторах.


Ну о возможной реализации можно еще поспорить, мало ли компиляторов на белом свете. А узнать о ее наличии или отсутствии было интересно.
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2096 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.