
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (78) « Первая ... 23 24 [25] 26 27 ... 77 78 ( Перейти к последнему сообщению ) |
Сообщ.
#361
,
|
|
|
Да. lambda branch действительно смерджили с основным транком gcc. Помимо лямбд там появятся:
- Explicit conversion operators - Standard Layout Types - Local and unnamed types as template arguments Добавлено Последняя фишка весьма забавная, надо отметить. |
Сообщ.
#362
,
|
|
|
Цитата archimed7592 @ T t; // lvalue T &rt = t; // lvalue reference T &&rrt = t; // rvalue reference Я что-то не пойму ссылка на ссылку объявляется так как в примере выше? Я просто думал, что так ![]() ![]() T t; T &rt = t; T &&rrt = rt; |
Сообщ.
#363
,
|
|
|
Цитата Большой @ Я что-то не пойму ссылка на ссылку объявляется так как в примере выше? Да. Добавлено Вопрос к Masterkent'у. Masterkent, не известно ли тебе - по какой причине в новой версии стандарта всё еще запрещено объявлять шаблонные члены в локальных классах? Просто забавно получается - в качестве шаблонных параметров их разрешили использовать, а шаблонизировать сами эти классы - нет. Иначе как было бы здорово (на мой взгляд) объявлять полиморфные функторы: ![]() ![]() // Некий обобщенный код: template<typename T1, typename T2, typename F> void generic_foo(T1 a, T2 b, F fn) { // ... fn(a, b); // ... } void foo(int a, double b) {} void foo(std::string a, char b) {} void bar() { class FTor { template<typename T1, typename T2> void operator()(T1 a, T2 b) {foo(a, b);} } ftor; generic_foo(10, 103.2, ftor); generic_foo(std::string("abeagew"), 'a', ftor); } Но... Так нельзя... ![]() |
![]() |
Сообщ.
#364
,
|
|
Цитата Большой @ Я что-то не пойму ссылка на ссылку объявляется так как в примере выше? Это не ссылка на ссылку. Это rvalue ссылка (в отличии от lvalue ссылки). Разница между ними настолько же существенная, как и между указателем и ссылкой. |
Сообщ.
#365
,
|
|
|
archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue?
или опять я туплю |
Сообщ.
#366
,
|
|
|
Цитата Большой @ archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue? Да. |
![]() |
Сообщ.
#367
,
|
|
Цитата Большой @ archimed7592т.е. ты хочешь сказать, что это не ссылка на ссылку, а правильнее говорить ссылка на rvalue? или опять я туплю 1. Это не ссылка на ссылку. 2. Это называется rvalue reference, а как правильнее обзывать - решай сам. 3. Базовую информацию о том, что такое rvalue reference и чем она отличается от lvalue reference ты можешь получить в первом посте. 4. Зная что представляет из себя ссылка по определениям C++03 (а это определение сильно не изменилось в С++09), ты бы понимал, что ссылка на ссылку - это некая абстрактная сущность (которой к слову в С++09 не появилось), которая не имеет абсолютно никакого смысла. Объясню про п. 4 чуть подробнее. Есть такое понятие как указатель на указатель на T. Смысл этой сущности состоит в том, что с её помощью можно изменять значение некоторого объекта ссылающегося на объект типа T, т.е. модифицировать указатель. ![]() ![]() int x, y; int *pi = &x, **ppi = π x = 10; y = 20; std::cout << *pi << std::endl; // 10; x += 5; std::cout << *pi << std::endl; // 15; *ppi = &y; std::cout << *pi << std::endl; // 20; y += 5; std::cout << *pi << std::endl; // 25; Что же касается ссылки - связь с объектом на который она указывает ссылка получает во время инициализации и изменить эту связь таким образом, чтобы ссылка ссылалась на другой объект в принципе невозможно (формально, да, можно подменить объект в памяти другим при помощи new (ptr) T(), но изменением связи это назвать сложно). Тот факт что технически ссылка может представлять из себя объект, указывающий на другой объект, т.е. указатель никаким образом не помогает нам изменить связь ссылки с объектом, если так будет проще: в С++ не предусмотрено для этих целей синтаксиса; ни в С++03, ни в С++09. Для более лёгко понимания того, что из себя представляет ссылка в некоторой литературе советуют воспринимать ссылку как синоним имени объекта для доступа к нему. Как ты сам понимаешь синоним на синоним всё равно будет представлять из себя синоним. |
Сообщ.
#368
,
|
|
|
Цитата Flex Ferrum @ Masterkent, не известно ли тебе - по какой причине в новой версии стандарта всё еще запрещено объявлять шаблонные члены в локальных классах? Не знаю. IMHO, скорее всего, такое в принципе возможно формализовать (без получения негативных побочных эффектов), но комитет просто не видит в этом достаточной выгоды, чтобы переписывать правила. |
Сообщ.
#369
,
|
|
|
Цитата Flex Ferrum @ Да. lambda branch действительно смерджили с основным транком gcc. Помимо лямбд там появятся: - Explicit conversion operators - Standard Layout Types - Local and unnamed types as template arguments Насчет последнего - local понятно, но unnamed это как? Чтото вроде этого: ![]() ![]() template <class T> class A {...}; void foo() { A<struct {int a; int b;}> obj; } ? ПС Еще обещают в gcc 4.5 повысить скорость компиляции шаблоного кода и добавить Link-time оптимизацию. Так глядишь и студийный компилятор по скорости догонит... |
Сообщ.
#370
,
|
|
|
Цитата pan2004 @ ПС Еще обещают в gcc 4.5 повысить скорость компиляции шаблоного кода и добавить Link-time оптимизацию. Уже. ![]() |
Сообщ.
#371
,
|
|
|
Цитата pan2004 @ но unnamed это как? Класс или перечисление получается безымянным, когда в его определении непосредственно после ключевого слова class, struct, union или enum отсутствует имя. ![]() ![]() struct NamedClass {}; enum NamedEnumeration { enumerator_of_named_enumeration_type }; typedef struct : NamedClass {} UnnamedClass; // has name for linkage purposes only enum { enumerator_of_unnamed_enumeration_type }; template <class T> void f(T) {} int main() { f(NamedClass()); // well-formed in C++03 and C++0x f(enumerator_of_named_enumeration_type); // well-formed in C++03 and C++0x f(UnnamedClass()); // ill-formed in C++03, well-formed in C++0x f(enumerator_of_unnamed_enumeration_type); // ill-formed in C++03, well-formed in C++0x } Цитата pan2004 @ Чтото вроде этого: ![]() ![]() template <class T> class A {...}; void foo() { A<struct {int a; int b;}> obj; } ? Так делать нельзя: Цитата N2914 - 14.3/1 template-argument:
constant-expression
type-id
id-expression Цитата N2914 - 8.1/1 type-id:
type-specifier-seq attribute-specifieropt abstract-declaratoropt Цитата N2914 - 7.1.6/3 A type-specifier-seq shall not define a class or enumeration unless it appears in the type-id of an alias-declaration |
Сообщ.
#372
,
|
|
|
Цитата Masterkent @ Класс или перечисление получается безымянным, когда в его определении непосредственно после ключевого слова class, struct, union или enum отсутствует имя. Можешь привести пример (пусть и синтетический) но более-менее реального применения этой фишки? |
Сообщ.
#373
,
|
|
|
Цитата Flex Ferrum @ Можешь привести пример (пусть и синтетический) но более-менее реального применения этой фишки? Перечислениям довольно часто не дают имени, ну а безымянные классы лично мне не пригождались - за исключением анонимных union-ов, но ими шаблоны по-любому не инстанцируешь. |
Сообщ.
#374
,
|
|
|
Цитата Masterkent @ Перечислениям очень часто не дают имени, ну а безымянные классы лично мне не пригождались. Ну, вообще говоря, по-моему, отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов... У них ведь, вроде как (у констант, в смысле) получается тип int. Или я чего-то недопонимаю? |
Сообщ.
#375
,
|
|
|
Цитата Flex Ferrum @ отсутствие имени у таких перечислений не мешало мне использовать их в качестве параметров шаблонов VC++ позволяет инстанцировать шаблоны безымянными типами. Цитата Flex Ferrum @ У них ведь, вроде как (у констант, в смысле) получается тип int. Цитата C++03 - 7.2/4 Each enumeration defines a type that is different from all other types. Following the closing brace of an enum-specifier, each enumerator has the type of its enumeration. |