Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180

Еще немного про конструкторы обобщенных классов

14.01.2017, 08:43. Показов 2319. Ответов 32

Пытаюсь проинициализировать объект обобщенного класса, параметром которого может выступать ссылка.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
template<typename T>
struct A {
    T d;
    A(const T& _d) : d(_d) {std::cout << "cT&\n";};
    A(T&& _d) : d(std::forward<T>(_d)) {std::cout << "T&&\n";};
};
 
int i = 3;
 
int main() {
    A<int&> a(i);
}
В таком виде оно ругается на перегрузку ссылочного конструктора.
Если убрать
C++
1
A(const T& _d)
будет ругаться на нессылочные типы.

Как строить такие объекты?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.01.2017, 08:43
Ответы с готовыми решениями:

Конструкторы классов
Схематично: class A {public: A() {}//конструктор А . . . //методы класса А } class B: public A {public: B()...

Конструкторы классов
Помогите разобраться с классами, не пойму как мне сделать правильно конструкторы класса Application,выдвёт ошибки в его конструкторе,...

Еще немного по теории
Автоматы в программировании. Виртуальная ф-ция Что такое template, pattern? Разница Запуск исключений? до сих пор не пойму разнице...

32
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
14.01.2017, 12:05
Цитата Сообщение от Mirmik Посмотреть сообщение
возможность возвращения ошибок вместо результата.
В чём проблема плеваться экзепшонами, как это делают все нормальные программы?
Цитата Сообщение от Mirmik Посмотреть сообщение
Своеобразная замена исключениям в стиле rust.
Это плохо. Не надо пытаться перенести фишки одного языка в другой язык, это как постоянно проверять типы, которые содержит переменная в питоне, к примеру.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
14.01.2017, 12:13  [ТС]
Неплохо.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <experimental/any>
 
template<typename T>
struct A {
    std::experimental::any d;
 
    A(T _d) : d(_d) {}
 
    operator T() {return std::experimental::any_cast<T>(d);}
};
 
int i = 3;
 
A<int&> func() {
    return i;
}
 
int main() {
    std::cout << func() << std::endl; 
}
Осталось разобраться в том, как any работает.

Добавлено через 2 минуты
GbaLog-, я микроконтроллерщик. Компилятор gcc-avr, например вообще не поддерживает исключения. Да и для других ядер исключения местами тяжеловесны.
И потом, я вижу преимущества у этого метода. Например в том, что исключения точно не вываляться за пределы safe ветки.

Так или иначе, я попробую. Никто от этого не умрёт.
0
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
14.01.2017, 12:14
Или можно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <limits>
/////////////////////////////////////////////////////////////////////////////////////////
bool foo(int& value)
{
    if(value < 0)
        return false;
    return true;
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    int n = std::numeric_limits<int>::max() + 1;
    if(foo(n))
        std::cout << "success\n";
    else
        std::cout << "error\n";
    
    if(foo(--n))
        std::cout << "success\n";
    else
        std::cout << "error\n";
}
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
14.01.2017, 13:15  [ТС]
Вообще, any это плохо, наверное... Он наверняка какие-то преобразования внутри делает

Добавлено через 51 минуту
Не, не, не. Там будет union возвращаемого типа и типа error. И переменная, указывающая, кем оно является. Впринципе оно уже работает.

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
template<typename T> 
struct abstract {
    T data;
    abstract(T d) : data(d) {}
    operator T() {return data;}
};
 
template<typename T> 
struct abstract<T&> {
    T& data;
    abstract(T& d) : data(d) {};
    //abstract(T&& d) : data(d) {};
    operator T&() {return data;}
};
 
template<typename T> 
struct abstract<T&&> {
    T&& data;
    abstract(T& d) : data(std::move(d)) {};
    abstract(T&& d) : data(std::move(d)) {};
    operator T&&() {return std::move(data);}
};
 
template<typename T>
struct A {
    abstract<T> d;
    template<typename UT>
    A(UT&& _d) : d(std::forward<UT>(_d)) {}
    operator T() {return d;}
};
 
template<>
struct A<void> {
    A(){}
};
 
int main() {
    int iii = 3;
 
    A<int> a0(3);
    //A<int&> a1(3); //nocondition
    A<int&&> a2(3);
 
    A<int> a3(iii);
    A<int&> a4(iii);
    A<int&&> a5(iii);
 
    A<int> a6(std::move(iii));
    //A<int&> am7(std::move(iii)); //nocondition
    A<int&&> a8(std::move(iii));
 
    A<void> av;
 
    std::cout << a0 << std::endl;
    //std::cout << a1 << std::endl;
    std::cout << a2 << std::endl;
    std::cout << a3 << std::endl;
    std::cout << a4 << std::endl;
    std::cout << a5 << std::endl;
    std::cout << a6 << std::endl;
    //std::cout << a7 << std::endl;
    std::cout << a8 << std::endl;
}
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
14.01.2017, 15:53
Цитата Сообщение от Mirmik Посмотреть сообщение
C++
1
A<int&&> a2(3);
Это UB. Получишь "висячую ссылку".

Добавлено через 9 минут
Цитата Сообщение от Mirmik Посмотреть сообщение
C++
1
2
template<typename UT> 
A(UT&& _d) : d(std::forward<UT>(_d)) {}
Здесь тоже будет UB, в случае, если UT отличается от T, и T у нас - r-ссылочный.
Например:
Code
1
2
3
4
5
UT = double, T = int &&, 
int && - параметр конструктора abstract<int &&>
т.к. UT - double, будет выполнено создание временного объекта, 
 который будет привязан к ссылке int && d = int(_d)
итого, в конце выражения опять получаем висячую ссылку.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
14.01.2017, 22:48  [ТС]
Если эта висячая ссылка получается и при попытке обычного return, то собственно так и должно быть. То есть это не мой UB а стандартный. Если обычный возврат ссылки приводит к UB, то и обреззалтченный тоже должен. Но, это все конечно требует анализа.

Добавлено через 2 минуты
А UT я перепишу на ремув референс, наверное...
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
15.01.2017, 01:19
Цитата Сообщение от Mirmik Посмотреть сообщение
Если эта висячая ссылка получается и при попытке обычного return, то собственно так и должно быть.
return тут не при чем.

Добавлено через 10 минут
Цитата Сообщение от Mirmik Посмотреть сообщение
То есть это не мой UB а стандартный.
Да ничего подобного!

Вот этот код абсолютно легальный, т.к. здесь продлевается время жизни временного объекта:
C++
1
int && r = 3;
А вот этот приводит к висячей ссылке:
C++
1
A<int &&> a2(3);
Т.е. в первом случае мы можем обратиться к r и корректно работать через нее с объектом, а во втором случае объект уже будет мертв.

12.2/5
The second context is when a reference is bound to a temporary.117 The temporary to which the reference is
bound or the temporary that is the complete object of a subobject to which the reference is bound persists
for the lifetime of the reference
except:
  • (5.1) — A temporary object bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
  • (5.2) — The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not
    extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • (5.3) — A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the
    full-expression containing the new-initializer. [ Example:
    C++
    1
    2
    3
    
    struct S { int mi; const std::pair<int,int>& mp; };
    S a { 1, {2,3} };
    S* p = new S{ 1, {2,3} }; // Creates dangling reference
    end example ] [ Note: This may introduce a dangling reference, and implementations are encouraged
    to issue a warning in such a case. — end note ]
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
15.01.2017, 09:35  [ТС]
Хм... Я понял.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
22.01.2017, 18:25  [ТС]
DrOffset, но ведь при возвращении из функции, объект на стеке, на который ссылается ссылка, все равно будет уничтожен, верно? то есть после return жизнь объекта не продлевается. А значит, разницы в поведении не будет, если мой объект кнструируется только при return. Верно?

C++
1
2
3
4
A<B&&> fff() {
    B b(2);
    return std::move(b);
}

C++
1
2
3
4
B&& fff() {
    B b(2);
    return std::move(b);
}
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,822
22.01.2017, 18:58
Цитата Сообщение от Mirmik Посмотреть сообщение
Верно?
Верно.

Но я вообще-то говорил про другой случай. И уже дал это понять фразой выше
Цитата Сообщение от DrOffset Посмотреть сообщение
return тут не при чем.
Я не знаю зачем ты все время возвращаешься именно к возврату из функции. Речь не о UB при возврате из функции, а о UB при сохранении в классе ссылки на объект, переданный в конструктор. Если этот объект - временный, то ссылка будет "висячей". Пример
Цитата Сообщение от Mirmik Посмотреть сообщение
A<int&&> a2(3);
именно об этом, не о возврате из функции, нет.

PS. Почти везде в твоих кодах ты совершенно неуместно применяешь std::move. Наверное надо с этим что-то сделать?
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
23.01.2017, 12:32  [ТС]
ОК. Я понял, почему и когда возникает UB.

Я не знаю зачем ты все время возвращаешься именно к возврату из функции
Потому что я конструирую класс-обёртку над возвращаемым значением.

Объекты данного класса никогда не будут конструироваться явно.

C++
1
2
3
result<int> func() {
    return 3;
}
Конструктор будет вызываться всегда перед возвратом из функции. Я хочу добиться того, чтобы данная обёртка вела себя максимально схоже с:
C++
1
2
3
int func() {
    return 3;
}
(С учетом того, что возвращаться также могут ссылки или void.)

move - это от экспериментов. Я не очень хорошо понимаю, в каких случаях стоит использовать move, а в каких можно положиться на NRVO... А в каких вообще не нужно этого всего делать. Это тоже предмет текущего исследования...
0
Каждому свое
 Аватар для Bretbas
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
24.01.2017, 19:06
Mirmik,
Цитата Сообщение от Mirmik Посмотреть сообщение
Я не очень хорошо понимаю, в каких случаях стоит использовать move, а в каких можно положиться на NRVO...
"Эффективный и современный C++" Скотта Мэйерса, там есть про это очень доходчиво
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
25.01.2017, 10:39  [ТС]
Благодарю. Посмотрю обязательно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.01.2017, 10:39

Наследование классов и конструкторы
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; class form { public: form(){printf(&quot;form::form()\n&quot;);}; ...

Классы, конструкторы, деструкторы, методы классов
Доброго времени суток , Господа программисты. :) Очень нужна Ваша помощь. Написал программу, но никак не получается сделать последний...

Конструкторы классов в неявно подключенных DLL
Добрый день, господа программисты! Столкнулся с парой проблем при работе с DLL При написании классов внутри DLL, компилятор не...

Про линковку библиотек и про архитектуру иерархии классов
Добрый день! Возникла такая вот проблема. Я использую MinGW Developer Studio. Это довольно старая IDE, поддержка которой завершилась в 2005...

Как создавать конструкторы, что бы использовать переменные из любых классов?
В общем пишу программку, суть в том , что я должен научиться спокойно использовать переменные из разных классов в разных классах и в int...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
33
Ответ Создать тему
Новые блоги и статьи
[golang] Worker Pool
alhaos 09.06.2026
Worker Pool Worker Pool — паттерн конкурентной обработки задач в Go. Суть: фиксированное количество горутин-воркеров читают задачи из общего канала и пишут результаты в общий канал результатов. . . .
[golang] Pipeline
alhaos 08.06.2026
Pipeline Pipeline — паттерн конкурентной обработки данных в Go. Суть: данные проходят через цепочку независимых стадий, каждая из которых работает в своей горутине и общается с соседями через. . .
Свет внутри себя
kumehtar 07.06.2026
Пусть это будет здесь lIs4oanZS9Y
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru