HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- с++: опять запутался в трёх соснах. (https://hlfx.ru/forum/showthread.php?threadid=4795)
Отправлено thambs 30-06-2016 в 12:29:
с++: опять запутался в трёх соснах.
Понадобился мне тут класс для квадратных матриц, но не могу понять что за ошибка лезет:
C++ Source Code:
8 | CMatrix(size_t n): size(n){ |
9 | data = new T [size*size]; |
11 | CMatrix(const CMatrix& other){ |
13 | data = new T [size*size]; |
14 | for(size_t x=0; x<size; x++){ |
15 | for(size_t y=0; y<size; y++){ |
17 | data[size*x+y] = other.data[size*x+y]; |
19 | self(x,y) = other(x,y); |
20 | // получаем error: passing ‘const CMatrix<float>’ as ‘this’ argument of ‘T& CMatrix<T>::operator()(const size_t&, const size_t&) [with T = float; size_t = long unsigned int]’ discards qualifiers [-fpermissive] |
27 | T &operator()(const size_t& x, const size_t& y){ |
28 | return data[size*x+y]; |
Как это по человечески сделать?__________________
http://www.moddb.com/mods/monorail-quest
Отправлено FreeSlave 30-06-2016 в 12:42:
thambs, ты пытаешься вызвать неконстантную функцию на константном объекте (other).
Нужно продублировать оператор скобок с квалификатором const:
Отправлено Дядя Миша 30-06-2016 в 19:06:
Цитата:
thambs писал:
#define self (*this)
улыбнуло__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено pRoxxx 01-07-2016 в 14:34:
А чем тебе работающий вариант не подходит? Или у тебя задача сделать код максимально не читаемым?
Отправлено thambs 20-07-2016 в 18:05:
А подскажите про Variadic functions -- я уже себе весь мозг сломал. Везде эта зараза требует что бы был указан хотя бы один аргумент. Мне нужно, что бы можно было единообразно вызвать функцию от любого (и нулевого) числа однотипных аргументов, а их колчиество задавалось, например, в шаблоне. Как тогда обойтись без va_start?
__________________
http://www.moddb.com/mods/monorail-quest
Отправлено XaeroX 20-07-2016 в 18:37:
Цитата:
thambs писал:
Везде эта зараза требует что бы был указан хотя бы один аргумент.
Нет, это не так. Вернее, это так только для С. В С++ ты можешь спокойно скомпилить вот такое:
C++ Source Code:
int foo(...) { return 42; } |
Цитата:
thambs писал:
Как тогда обойтись без va_start?
Необходимость сочетать va_start и шаблоны - признак плохого стиля кодирования. Используй std::initializer_list или variadic templates.
Если всё же есть желание натягивать сову на глобус - могу предложить получать доступ к аргументам напрямую из стека, используя ассемблерные вставки. 
__asm в шаблонах гарантированно снесёт мозг любому код-ревьюверу.
)__________________
Отправлено thambs 20-07-2016 в 19:01:
>std::initializer_list или variadic templates
нашёл вот такой http://nerdparadise.com/forum/openmic/5712/ вариант, но как-то через рекурсивный шаблон уродливо. Получается, придётся на каждую функцию завершающий дублёр писать... Это уже haskell какой-то получается.
>ассемблерные вставки
это плохо, хотелось бы чего ни будь в стиле:
C++ Source Code:
for(n=0;n<n_dim;n++) x=xs[n]; |
__________________
http://www.moddb.com/mods/monorail-quest
Отправлено XaeroX 20-07-2016 в 22:03:
Цитата:
thambs писал:
это плохо, хотелось бы чего ни будь в стиле
Не факт, что все аргументы будут одного типа. Более того, не факт, что все они одного размера.
Но в принципе std::initializer_list как раз и делает то, что тебе нужно.__________________
Отправлено Дядя Миша 21-07-2016 в 16:39:
Цитата:
XaeroX писал:
Вернее, это так только для С. В С++ ты можешь спокойно скомпилить вот такое:
Достаточно указывать тип аргумента, имя уже необязательно 
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено thambs 21-07-2016 в 16:47:
>имя уже необязательно
А доступ к ним как получать?
>std::initializer_list
Вызов будет f({arg1, arg2, ...}), эти скобки убрать что бы выглядело как обычная функция.
__________________
http://www.moddb.com/mods/monorail-quest
Отправлено Дядя Миша 21-07-2016 в 17:25:
Цитата:
thambs писал:
А доступ к ним как получать?
ну, через ассемблер к примеру
по смещению. Или как-нибудь получить указатель на функцию внутри самой себя и посчитать смещение до первого аргумента (+4 байта). Но я не уверен что компилятор такое прожует, да и ни к чему это.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено ComradeAndrew 21-07-2016 в 18:07:
thambs
А такой вариант устраивает?
C++ Source Code:
1 | template<typename... Ts> void func(Ts... args){ |
2 | const int size = sizeof...(args) + 2; |
3 | int res[size] = {1,args...,2}; |
4 | // since initializer lists guarantee sequencing, this can be used to |
5 | // call a function on each element of a pack, in order: |
6 | int dummy[sizeof...(Ts)] = { (std::cout << args, 0)... }; |
source
Если в функцию не подается аргументов, то можно использовать либо константную проверку (правда она вроде только в C++17)
Ну или можно использовать std::vector
C++ Source Code:
std::vector<int> v{ args... }; |
Ну смысл ты понял.
Отправлено thambs 21-07-2016 в 21:04:
ComradeAndrew
Вот это то что надо, только я не могу понять как оно работает:
C++ Source Code:
const int n_args = sizeof...(args); |
int dummy[n_args] = { args... }; //вот тут оно разворачивается вообще без проверки типов, или там есть неявное приведение? |
в чём разница между C++ Source Code:
и C++ Source Code:
?__________________
http://www.moddb.com/mods/monorail-quest
Отправлено ComradeAndrew 22-07-2016 в 06:51:
thambs
Никакой разницы. И то и то компилируется вот в это