Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

C++

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 5.00
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
#1

Перенаправление указателя при перегрузке оператора в variadic template - C++

18.04.2015, 16:19. Просмотров 1404. Ответов 35
Метки нет (Все метки)

Есть вот такой вот код (сделан в vs2014):
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"
#include "windowsx.h"
 
using namespace std;
 
int Cur = 0;
 
struct var
{
    int ps; // pointer size
    union
    {
        bool b;
        int i;
        PVOID vp;
        char *pc;
        void *pv;
        int *pi;
        double *pd;
        operator bool & ()
        {
            cout << "### Bool overload operator" << endl;
            return b;
        }
        operator int & ()
        {
            cout << "### Int overload operator" << endl;
            return i;
        }
        operator int * ()
        {
            cout << "### POINTER Int overload operator" << endl;
            return pi;
        }
        operator double * ()
        {
            cout << "### POINTER Double overload operator" << endl;
            return pd;
        }
        operator double & ()
        {
            cout << "### Double overload operator" << endl;
            return pd[0]; // вот тут вопрос
        }
        operator PVOID & ()
        {
            cout << "### PVOID overload operator" << endl;
            return vp;
        }
        operator char * ()
        {
            cout << "### Char[] overload operator" << endl;
            return pc;
        }
        operator void * ()
        {
            cout << "### Void[] overload operator" << endl;
            return pv;
        }
    }d;
};
var **v;
 
template<typename Result, typename... Args>
void call(void * fun, Result& r, Args ... args)
{
    using func_type = Result(_cdecl *)(Args...); // прототип функции
    r = ((func_type)fun) (args...); // вызов функции
}
 
int SomeFunc2();
 
int _tmain(int argc, _TCHAR* argv[])
{
    if(SomeFunc2()==0)
        cout << "End Programm" << endl;
    _getch();
    return 0;
}
 
int SomeFunc2()
{
    int res = 0;
    int b = 2;
    v = new var*[b];//динамическая матрица
    v[0] = new var[10];
    v[1] = new var[6];
    v[0][0].d.i = 10;
    v[0][1].d.pc = new char[100];
    v[0][2].d.pc = new char[100];
    v[0][3].d.vp = NULL;
    v[0][4].d.vp = NULL;
    v[0][5].d.i = NULL;
    v[0][6].d.i = 100;
    v[0][7].d.pc = new char[100];
    v[0][8].d.i = 99;
    v[0][9].d.i = 10;
    //
    v[1][0].d.i = 6;
    v[1][1].d.i = NULL;
    v[1][2].d.pd = new double[10];
    v[1][3].d.pc = new char[100];
    v[1][4].d.i = 99;
    v[1][5].d.i = 10;
    //
    strcpy_s(v[0][1].d.pc, v[0][8].d.i, "msvcr120.dll");
    //
    for (int i = 0; i < 10; i++)
    {
        v[1][2].d.pd[i] = NULL;
    }
    strcpy_s(v[1][3].d.pc, v[1][4].d.i, "123.32");
    // test call with pd[0]
    v[1][2].d.pd[0] = atof(v[1][3].d.pc);
    cout << "Test atof result: " << v[1][2].d.pd[0] << endl;
    v[1][2].d.pd[0] = 0;
    //
    cout << "Library Name: " << v[0][1].d.pc << endl;
    int go = 0;
    v[0][3].d.vp = GetModuleHandleA(v[0][1].d);
    if (!v[0][3].d.vp)
    {
        cout << "Library -NOT- found, try load..." << endl;
        v[0][3].d.vp = LoadLibraryA(v[0][1].d);
        if (!v[0][3].d.vp)
            cout << "Library -NOT- loaded" << endl;
        else
        {
            cout << "Library loaded" << endl;
            go = 2;
        }
    }
    else
    {
        cout << "Library found" << endl;
        go = 1;
    }
    if (go != 0)
    {
        strcpy_s(v[0][2].d.pc, v[0][8].d.i, "atof");//_itoa_s
        cout << "Function Name: " << v[0][2].d.pc << endl;
        v[0][4].d.vp = GetProcAddress((HMODULE)v[0][3].d.vp, v[0][2].d.pc);
        if (!v[0][4].d.vp)
            cout << "Function -NOT- found" << endl;
        else
        {
            cout << "Function found, try call..." << endl;
            //call(v[0][4].d.vp, v[1][1].d, v[1][2].d, v[1][3].d, v[1][4].d, v[1][5].d);
            //call(v[0][4].d.vp, v[1][2].d.pi[0], v[1][3].d);
            //call(v[0][4].d.vp, v[1][2].d, v[1][3].d);
            //v[1][1].d.i = atoi(v[1][3].d.pc);
            Cur = 0;
            //v[1][2].d.pd[Cur] = atof(v[1][3].d.pc); // double
            //call(v[0][4].d.vp, v[1][2].d.pd[Cur], v[1][3].d);
            call(v[0][4].d.vp, v[1][2].d, v[1][3].d);
            if (v[1][2].d.pd[Cur] == NULL)
                cout << "Failed result, error: " << endl;
            else
            {
                //char fStr[100] = "";
                //sprintf_s(fStr, sizeof(fStr), "%f", v[1][2].d.pd[Cur]);
                cout << "Returned DOUBLE PTR[" << Cur << "]: " << v[1][2].d.pd[Cur] << endl;
            }
        }
        if (go == 2)
        {
            FreeLibrary((HMODULE)v[0][3].d.vp);
            cout << "Library cleaned" << endl;
        }
    }
    delete[]v[0][7].d.pc;
    delete[]v[0][2].d.pc;
    delete[]v[0][1].d.pc;
    delete[]v[0];
    delete[]v[1][3].d.pc;
    delete[]v[1][2].d.pd;
    delete[]v[1];
    delete[]v;
    return res;
}
Я не хочу вводить в вложенный юнион перменную double, вместо этого хочу чтоб нужная переменная вызывалась из указателя.

Как видится всё это... Вот это должно по сути сработать... (пока что статически написан "0", в будущем конешно хотелось бы тоже поправить, чтоб можно было изменить, для этого int Cur хотел использовать)
C++
1
2
3
4
5
operator double & ()
        {
            cout << "### Double overload operator" << endl;
            return pd[0]; // вот тут вопрос
        }
При выполении программы правильно работает только тест, где явно указано где что брать:
C++
1
v[1][2].d.pd[0] = atof(v[1][3].d.pc);
Потом уже при "не явном вызове" уже происходит ошибка, и получается что перегруженный оператор не срабатывает.
C++
1
call(v[0][4].d.vp, v[1][2].d, v[1][3].d);
Я так понимаю что шаблон всё равно ссылается на адрес v[1][2].d, а ведь я предполагал, что перегруженный оператор должен перенаправить адрес в указатель pd[0].

И ещё, смежный вопрос, как в самом шаблоне проверить какой тип требуется и адрес.
Т.е. хотелось бы чтоб в шаблоне можно было тоже следить за поведением переменных.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.04.2015, 16:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Перенаправление указателя при перегрузке оператора в variadic template (C++):

Variadic templates, или variadic constructor в шаблоне, или прочие извращения - C++
Здравствуйте. Есть такое Wrapper&lt;Obj&gt; w; Wrapper - обертка над объектом того класса, который ему скормят (в данном случае - Obj)....

Встроенный оператор C++ откликается при перегрузке - C++
Вот возникает ошибочка, кажется я понимаю почему List&lt;int&gt; abc; abc &lt;&lt; 1 &lt;&lt; 5; Имеется у списка собственно LIST&amp; operator...

Ошибка при комилировании. Cannot use template 'texnika<T>' without specifying specialization parameters - C++ Builder
Выходит вот такая ошибка: Unit1.cpp(34): E2102 Cannot use template 'texnika&lt;T&gt;' without specifying specialization parameters ...

Передача в метод по перегрузке оператора указателя на объект - C++
У нас есть массив указателей на базовый класс STRING **ptr = new STRING* ; for (int i = 0; i&lt;size; ++i) { ...

Variadic template - C++
Добрый день, господа. Будьте добры, помогите кто может. Есть у меня шаблонный класс template&lt;typename ... Types&gt; Class :...

recursion with variadic template - C++
#define NOT_COMPILE 1 #if NOT_COMPILE // так не компилится template &lt;class Type, unsigned int head, unsigned int ... rest &gt; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
20.04.2015, 13:31  [ТС] #2
Ну так шо, нету никаких соображений?..
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
20.04.2015, 18:56 #3
Очень уж запутанный и непонятный вопрос. Выражения вроде "хочу, чтобы нужная переменная вызывалась из указателя" и "шаблон ссылается на адрес" тоже ясности не добавляют. А уж без понимания замысла, стоящего за этим нагромождением объединений и однобуквенных имён, разобраться совсем трудно. Ну и тексты сообщений об ошибке не повредили бы делу.
0
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
20.04.2015, 20:16  [ТС] #4
Цитата Сообщение от Nick Alte Посмотреть сообщение
хочу, чтобы нужная переменная вызывалась из указателя
В общем то это и хочу. Почему: хочу уменьшить размер uniona до 4 байт, для этого надо избавиться от 8 байтовых типов, как - либо их не использовать совсем (что невозможно просто, т.к. они нужны), либо использовать указатель на них, т.к. указатель 4 байтный, то это бы решило проблему, но не работает...

Цитата Сообщение от Nick Alte Посмотреть сообщение
тексты сообщений об ошибке
Line: 52

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
52 строка это:
Цитата Сообщение от Izual Посмотреть сообщение
return pd[0];
Уже как тока не пробовал... Никак... совсем. (и вообще мне кажется шаблон даже не обращяет внимание на перегруженный оператор, а ссылается именно к адресу переменной, т.е. к адресу v[1][2].d, но никак не к указателю на pd[0])
*Прикрепил принт ошибки.
И да, ошибка возникает при удалении "delete[] v[1][2].d.pd;" (потому что до "cout << "End Programm" << endl;" не доходит)
0
Миниатюры
Перенаправление указателя при перегрузке оператора в variadic template  
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
20.04.2015, 22:21 #5
Ошибка возникает из-за путаницы с выделением-освобождением (вероятно, какой-то участок памяти удаляется повторно).
0
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
20.04.2015, 22:31  [ТС] #6
Цитата Сообщение от Nick Alte Посмотреть сообщение
из-за путаницы с выделением-освобождением
НЕТ с выделением памяти и удалением всё ок.
Результат функции видели на картинке? Она выдаёт не верный ответ, а должен быть как в тестовом примере. Я предполагаю(УВЕРЕН!), что: при направлении v[1][2].d аргумента в шаблоне заполняется не pd элемент, а 8 байт начиная с "&v[1][2].d", т.е. не в указатель на pd[0], а сам .d адрес, в итоге затирается pd указатель на выделенный массив, и результат - невозможно удалить указатель, т.к. адрес к нему был затёрт результатом функции.
П.С. Я 100% нуб, и то понимаю это)))
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
21.04.2015, 18:54 #7
Ну тогда попробуем выяснить, вокруг чего такой кипеш. Функция call. Она получает указатель на функцию, у которого выдрана вся информация об аргументах и возвращаемом значении. Она получает пару экземпляров union, один из которых используется для получения результата, а другой передаётся в вызываемую функцию. Предполагается, что функция вернёт тот же union, который записывается в r. Однако же atof возвращает double, а не означенный union. Отсюда и проблемы. Половина возвращённого double впихивается в union и позже интерпретируется как указатель, а половина попросту теряется.
0
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
21.04.2015, 20:02  [ТС] #8
Цитата Сообщение от Nick Alte Посмотреть сообщение
функция вернёт тот же union, который записывается в r
ЧТо, куда? Указатель на функцию - это первый аргумент с типом PVOID. Второй аргумент - возвратное значение, тип POINTER DOUBLE. Третий параметр - аргумент самой функции "atof".
Цитата Сообщение от Izual Посмотреть сообщение
call(v[0][4].d.vp, v[1][2].d, v[1][3].d);
Тетстовый и работающий пример в коде:
Цитата Сообщение от Izual Посмотреть сообщение
v[1][2].d.pd[0] = atof(v[1][3].d.pc);
Цитата Сообщение от Nick Alte Посмотреть сообщение
atof возвращает double, а не означенный union
Atof возвращяет double, именно реальный, а не указатель, если бы он вернул указатель, то всё было бы ок.
О чём ты говориш я вообще не вдупляю. Пустословием не занимайся, явно покажи как исправить.
До этого я тестировал с такими поправками:
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "windows.h"
#include "windowsx.h"
 
using namespace std;
 
int Cur = 0;
 
struct var
{
    int ps; // pointer size
    union
    {
        bool b;
        int i;
        PVOID vp;
        char *pc;
        void *pv;
        int *pi;
        double *pd;
        double d; // поправка 1
        operator bool & ()
        {
            cout << "### Bool overload operator" << endl;
            return b;
        }
        operator int & ()
        {
            cout << "### Int overload operator" << endl;
            return i;
        }
        operator int * ()
        {
            cout << "### POINTER Int overload operator" << endl;
            return pi;
        }
        operator double * ()
        {
            cout << "### POINTER Double overload operator" << endl;
            return pd;
        }
        operator double & ()
        {
            cout << "### Double overload operator" << endl;
            return d; // поправка 2
        }
        operator PVOID & ()
        {
            cout << "### PVOID overload operator" << endl;
            return vp;
        }
        operator char * ()
        {
            cout << "### Char[] overload operator" << endl;
            return pc;
        }
        operator void * ()
        {
            cout << "### Void[] overload operator" << endl;
            return pv;
        }
    }d;
};
var **v;
 
template<typename Result, typename... Args>
void call(void * fun, Result& r, Args ... args)
{
    using func_type = Result(_cdecl *)(Args...); // прототип функции
    r = ((func_type)fun) (args...); // вызов функции
}
 
int SomeFunc2();
 
int _tmain(int argc, _TCHAR* argv[])
{
    if(SomeFunc2()==0)
        cout << "End Programm" << endl;
    _getch();
    return 0;
}
 
int SomeFunc2()
{
    int res = 0;
    int b = 2;
    v = new var*[b];//динамическая матрица
    v[0] = new var[10];
    v[1] = new var[6];
    v[0][0].d.i = 10;
    v[0][1].d.pc = new char[100];
    v[0][2].d.pc = new char[100];
    v[0][3].d.vp = NULL;
    v[0][4].d.vp = NULL;
    v[0][5].d.i = NULL;
    v[0][6].d.i = 100;
    v[0][7].d.pc = new char[100];
    v[0][8].d.i = 99;
    v[0][9].d.i = 10;
    //
    v[1][0].d.i = 6;
    v[1][1].d.i = NULL;
    v[1][2].d.d = NULL; // поправка 3
    v[1][3].d.pc = new char[100];
    v[1][4].d.i = 99;
    v[1][5].d.i = 10;
    //
    strcpy_s(v[0][1].d.pc, v[0][8].d.i, "msvcr120.dll");
    /* поправка 4
    for (int i = 0; i < 10; i++)
    {
        v[1][2].d.pd[i] = NULL;
    }*/
    strcpy_s(v[1][3].d.pc, v[1][4].d.i, "123.32");
    // test call with pd[0]
    v[1][2].d.d = atof(v[1][3].d.pc); // поправка 5 (чисто для теста)
    cout << "Test atof result: " << v[1][2].d.d << endl; // тут тоже поправка в выводе
    v[1][2].d.d = NULL; // и тут в обнулении после теста
    //
    cout << "Library Name: " << v[0][1].d.pc << endl;
    int go = 0;
    v[0][3].d.vp = GetModuleHandleA(v[0][1].d);
    if (!v[0][3].d.vp)
    {
        cout << "Library -NOT- found, try load..." << endl;
        v[0][3].d.vp = LoadLibraryA(v[0][1].d);
        if (!v[0][3].d.vp)
            cout << "Library -NOT- loaded" << endl;
        else
        {
            cout << "Library loaded" << endl;
            go = 2;
        }
    }
    else
    {
        cout << "Library found" << endl;
        go = 1;
    }
    if (go != 0)
    {
        strcpy_s(v[0][2].d.pc, v[0][8].d.i, "atof");//_itoa_s
        cout << "Function Name: " << v[0][2].d.pc << endl;
        v[0][4].d.vp = GetProcAddress((HMODULE)v[0][3].d.vp, v[0][2].d.pc);
        if (!v[0][4].d.vp)
            cout << "Function -NOT- found" << endl;
        else
        {
            cout << "Function found, try call..." << endl;
            Cur = 0;
            call(v[0][4].d.vp, v[1][2].d, v[1][3].d); // поправка 6
            if (v[1][2].d.d == NULL)
                cout << "Failed result, error: " << endl;
            else
            {
                cout << "Returned DOUBLE: " << v[1][2].d.d << endl; // поправка 7
            }
        }
        if (go == 2)
        {
            FreeLibrary((HMODULE)v[0][3].d.vp);
            cout << "Library cleaned" << endl;
        }
    }
    delete[]v[0][7].d.pc;
    delete[]v[0][2].d.pc;
    delete[]v[0][1].d.pc;
    delete[]v[0];
    delete[]v[1][3].d.pc;
    //delete[]v[1][2].d.pd; поправка 8
    delete[]v[1];
    delete[]v;
    return res;
}
И в данном случае всё работает. Но это не вариант, я хочу уменьшить размер uniona. Сделать это можно только если вместо реальной переменной типа double будет указатель на него.
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
21.04.2015, 20:24 #9
То, что ты не понимаешь, о чём я говорю, не значит, что я занимаюсь пустословием. Это значит, что тебе надо восполнять пробелы в знаниях, а также внимательно перечитывать непонятные места.
Так уж и быть, объясню повторно, специально для сумрачных гениев. Функция atof возвращает 8-байтовый double, согласно cdecl calling convention, это значение возвращается в регистрах EAX и EDX. В функции call написано:
C++
1
r = ((func_type)fun) (args...);
, причём про fun компилятор думает, что он возвращает твой union, занимающий 4 байта, а r в нашем случае - ссылка на v[1][2].d. То есть, половина вернувшегося числа, содержавшаяся в EAX, попадает в сыром виде внутрь v[1][2].d. Другая половина данных игнорируется. После того, как эти полчисла туда занесены, ты обращаешься с этой переменной как с указателем на double, каковым её содержимое категорически не является, и получаешь закономерный результат.
Как исправить - тут уж сам страдай, я в эту невменяемую кашу со стиранием типов лезть не хочу.
1
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
21.04.2015, 21:13  [ТС] #10
Цитата Сообщение от Nick Alte Посмотреть сообщение
про fun компилятор думает, что он возвращает твой union, занимающий 4 байта
Причём тут fun ? Это лишь указатель на функцию, не более. И он не имеет отношения к размеру double аргумента. Более того, я повторно показал код, который демонстрирует что с реальным double всё работает.
Цитата Сообщение от Nick Alte Посмотреть сообщение
для сумрачных гениев
Желчь можете оставить себе.
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
21.04.2015, 21:38 #11
Цитата Сообщение от Izual Посмотреть сообщение
Причём тут fun ? Это лишь указатель на функцию, не более.
При том, что при инстанциации шаблона call этому указателю явно вменяется определённый тип. В этом типе, помимо прочего, указано, что эта функция возвращает Result (то есть, тот самый многострадальный 4-байтный union). И когда в fun передаётся адрес atof (возвращающий результат в EAX:EDX), внутри данной инстанциации call всё равно генерируется вызов, соответствующий вменённому типу, игнорирующий содержимое EDX и заносящий содержимое EAX в v[1][2].d по ссылке. Ну и понятное дело, что при прямом вызове atof в твоём "примере, в котором всё работает" всё шоколадно: там-то в месте вызова имеется полная информация как об аргументе, так и о возвращаемом значении. А вот внутри call о переданной туда функции уже абсолютно ничего неизвестно, и приходится руководствоваться тем, что ты сообщишь. То есть, типом, к которому приводится fun, не имеющим ничего общего с atof кроме количества аргументов.
0
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
22.04.2015, 05:38  [ТС] #12
Цитата Сообщение от Nick Alte Посмотреть сообщение
типом, к которому приводится fun, не имеющим ничего общего с atof кроме количества аргументов
Так 8 байт же должно передаться, для этого и перегруженный оператор должен перенаправить результат в указатель, в котором есть место для этих 8 байт. Ведь если в функции явно аргумент или возвращяемое значение типа поинтера, то тоже всё шоколадно.
Цитата Сообщение от Nick Alte Посмотреть сообщение
полная информация как об аргументе, так и о возвращаемом значении
а для чего это шаблону? это запрашивает сама функция из списка аргументов в шаблоне, там уж что дадут то и будет, я потому и хочу подменить адрес с v[1][2].d на указатель... чтоб туда адрес значение писал.(в данном случае)

Добавлено через 4 минуты
C++
1
call(v[0][4].d.vp, v[1][2].d, v[1][3].d); // поправка 6
Точно так же неявно передаётся, и никакой информации не несёт. (.d тут это union, явным было бы v[1][2].d.d)
0
Nick Alte
Эксперт С++
1637 / 1009 / 119
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 1
22.04.2015, 19:03 #13
С какой бы стороны зайти, чтобы пробиться сквозь эту стену упрямого непонимания...
Вот все эти операторы преобразования - они работают тогда, когда есть несоответствие реального и ожидаемого типа.
В функции call такого несоответствия нет, там всё идеально совпадает. Потому что там из типов данных - только этот невменяемый union. Потому что именно он передаётся в call при вызове. union передаётся в call, union передаётся дальше в вызываемую функцию, возвращаемое ей значение интерпретируется как union и тупо побайтово копируется в r.
0
Izual
94 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,551
22.04.2015, 19:36  [ТС] #14
Цитата Сообщение от Nick Alte Посмотреть сообщение
С какой бы стороны зайти
Цитата Сообщение от Nick Alte Посмотреть сообщение
невменяемый union.
Чё ты прицепился к этому union'у? Меня интересует почему перегруженный оператор не срабатывает, и не перенаправляет double в pd[0]. ~ ~
0
DrOffset
7141 / 4282 / 965
Регистрация: 30.01.2014
Сообщений: 7,084
22.04.2015, 21:43 #15
Цитата Сообщение от Izual Посмотреть сообщение
Меня интересует почему перегруженный оператор не срабатывает, и не перенаправляет double в pd[0].
Он тебе на это и ответил. Для того, чтобы сработал оператор, нужно, чтобы, грубо говоря, в левой части выражения был требуемый тип. А там у тебя шаблон.
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
#include <cstdio>
 
struct Test
{
    operator int()
    {
        printf("Вызов оператора преобразования к int\n");
        return value; 
    }
    
    int value;
};
 
 
void test1(int x)
{
    printf("Функция, принимающая int\n");
}
 
template <typename T>
void test2(T x)
{
    printf("Функция, принимающая T\n");
}
 
int main()
{
    Test v = { 10 };
    
    test1(v); // здесь известен тип, к которому нужно преобразовать
    
    printf("-----------------------------\n");
    
    test2(v); // а здесь нет, поэтому шаблон подставит тот тип, который передали, т.е. Test     
}
Смотри поведение в рантайме здесь.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.04.2015, 21:43
Привет! Вот еще темы с ответами:

Ошибка при перегрузке оператора >> - C++
Приветствую. Есть 2 класса: enum Color { white = 1, red, green, blue, yellow }; class Shape { protected: Color figureCol; ...

Предупреждение при перегрузке оператора - C++
Есть вот такой код для созданный для обучения #include &lt;iostream&gt; using namespace std; class complex{ private: ...

Ошибка при перегрузке оператора + - C++
Имеется класс, который представляет из себя строку и количество символов в ней. Задача - перегрузить оператор +, чтобы он складывал нам две...

Variadic template lambda capture - C++
Доброго всем дня! Речь пойдёт об C++14, в котором стало возможным делать прямую передачу в замыкание: auto my_lambda = () { /*...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.04.2015, 21:43
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru