Модераторы: 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   Вверх
Страницы: (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.1407 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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