HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Технические вопросы > с++: опять запутался в трёх соснах.
Страницы (3): [1] 2 3 »   Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



с++: опять запутался в трёх соснах.

Понадобился мне тут класс для квадратных матриц, но не могу понять что за ошибка лезет:

C++ Source Code:
1
#define self (*this)
2
template <typename T>
3
class CMatrix{
4
  T *data = NULL;
5
public:
6
  size_t size;
7
public:
8
  CMatrix(size_t n): size(n){
9
    data = new T [size*size];
10
  }
11
  CMatrix(const CMatrix& other){
12
    size = other.size;
13
    data = new T [size*size];
14
    for(size_t x=0; x<size; x++){
15
      for(size_t y=0; y<size; y++){
16
        //вот так работает
17
        data[size*x+y] = other.data[size*x+y];
18
        //а вот так хрен вам!
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]
21
      }
22
    }
23
  }
24
  ~CMatrix(){
25
    delete [] data;
26
  }
27
  T &operator()(const size_t& x, const size_t& y){
28
    return data[size*x+y];
29
  }
30
}

Как это по человечески сделать?

__________________
http://www.moddb.com/mods/monorail-quest

Сообщить модератору | | IP: Записан
Сообщение: 156241

Старое сообщение 30-06-2016 12:29
- За что?
FreeSlave
Житель форума

Дата регистрации: Nov 2007
Проживает: Тула
Сообщений: 1077

Рейтинг



thambs, ты пытаешься вызвать неконстантную функцию на константном объекте (other).

Нужно продублировать оператор скобок с квалификатором const:

code:
T operator()(const size_t& x, const size_t& y) const { return data[size*x+y]; }

Сообщить модератору | | IP: Записан
Сообщение: 156242

Старое сообщение 30-06-2016 12:42
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32212
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
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'

Сообщить модератору | | IP: Записан
Сообщение: 156247

Старое сообщение 30-06-2016 19:06
-
pRoxxx
Житель форума

Дата регистрации: Jan 2011
Проживает: UA DP
Сообщений: 360
Возраст: 32

Рейтинг



А чем тебе работающий вариант не подходит? Или у тебя задача сделать код максимально не читаемым?

Сообщить модератору | | IP: Записан
Сообщение: 156290

Старое сообщение 01-07-2016 14:34
- За что?
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



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

__________________
http://www.moddb.com/mods/monorail-quest

Отредактировано thambs 20-07-2016 в 18:14

Сообщить модератору | | IP: Записан
Сообщение: 156920

Старое сообщение 20-07-2016 18:05
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34527
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
thambs писал:
Везде эта зараза требует что бы был указан хотя бы один аргумент.

Нет, это не так. Вернее, это так только для С. В С++ ты можешь спокойно скомпилить вот такое:
C++ Source Code:
int foo(...) { return 42; }

Цитата:
thambs писал:
Как тогда обойтись без va_start?

Необходимость сочетать va_start и шаблоны - признак плохого стиля кодирования. Используй std::initializer_list или variadic templates.
Если всё же есть желание натягивать сову на глобус - могу предложить получать доступ к аргументам напрямую из стека, используя ассемблерные вставки.
__asm в шаблонах гарантированно снесёт мозг любому код-ревьюверу. )

__________________

Сообщить модератору | | IP: Записан
Сообщение: 156923

Старое сообщение 20-07-2016 18:37
-
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



>std::initializer_list или variadic templates
нашёл вот такой http://nerdparadise.com/forum/openmic/5712/ вариант, но как-то через рекурсивный шаблон уродливо. Получается, придётся на каждую функцию завершающий дублёр писать... Это уже haskell какой-то получается.
>ассемблерные вставки
это плохо, хотелось бы чего ни будь в стиле:

C++ Source Code:
f(int xs...){
  for(n=0;n<n_dim;n++) x=xs[n];
}

__________________
http://www.moddb.com/mods/monorail-quest

Сообщить модератору | | IP: Записан
Сообщение: 156924

Старое сообщение 20-07-2016 19:01
- За что?
 XaeroX
Crystice Softworks

Дата регистрации: Oct 2005
Проживает: Торонто
Сообщений: 34527
Нанёс повреждений: 514 ед.
Возраст: 37

Рейтинг



Награды
 
[1 награда]


Цитата:
thambs писал:
это плохо, хотелось бы чего ни будь в стиле

Не факт, что все аргументы будут одного типа. Более того, не факт, что все они одного размера.
Но в принципе std::initializer_list как раз и делает то, что тебе нужно.

__________________

Сообщить модератору | | IP: Записан
Сообщение: 156932

Старое сообщение 20-07-2016 22:03
-
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32212
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
XaeroX писал:
Вернее, это так только для С. В С++ ты можешь спокойно скомпилить вот такое:

Достаточно указывать тип аргумента, имя уже необязательно

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'

Сообщить модератору | | IP: Записан
Сообщение: 156959

Старое сообщение 21-07-2016 16:39
-
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



>имя уже необязательно
А доступ к ним как получать?
>std::initializer_list
Вызов будет f({arg1, arg2, ...}), эти скобки убрать что бы выглядело как обычная функция.

__________________
http://www.moddb.com/mods/monorail-quest

Сообщить модератору | | IP: Записан
Сообщение: 156964

Старое сообщение 21-07-2016 16:47
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32212
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
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'

Сообщить модератору | | IP: Записан
Сообщение: 156965

Старое сообщение 21-07-2016 17:25
-
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



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)... };
7
}

source
Если в функцию не подается аргументов, то можно использовать либо константную проверку (правда она вроде только в C++17)
Ну или можно использовать std::vector
C++ Source Code:
std::vector<int> v{ args... };

Ну смысл ты понял.

Сообщить модератору | | IP: Записан
Сообщение: 156968

Старое сообщение 21-07-2016 18:07
- За что?
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



ComradeAndrew
Вот это то что надо, только я не могу понять как оно работает:

C++ Source Code:
const int n_args = sizeof...(args);
int dummy[n_args] = { args... }; //вот тут оно разворачивается вообще без проверки типов, или там есть неявное приведение?
в чём разница между
C++ Source Code:
sizeof...(args)
и
C++ Source Code:
sizeof...(Ts)
?

__________________
http://www.moddb.com/mods/monorail-quest

Сообщить модератору | | IP: Записан
Сообщение: 156973

Старое сообщение 21-07-2016 21:04
- За что?
ComradeAndrew
Житель форума

Дата регистрации: Aug 2014
Проживает: Дубай
Сообщений: 510
Возраст: 27

Рейтинг



thambs
Никакой разницы. И то и то компилируется вот в это

code:
const int size = sizeof...(args); mov dword ptr [size],2 const int sizeTs = sizeof...(Ts); mov dword ptr [sizeTs],2

С двумя аргументами соответственно.

Для вызовов с различными параметрами генерится соответствующая функция.

Добавлено 22-07-2016 в 09:51:

Цитата:
ComradeAndrew писал:
int dummy[n_args] = { args... }; //вот тут оно разворачивается вообще без проверки типов, или там есть неявное приведение?

Разворачивание происходит на этапе компиляции. Это будет обычная декларативная инициализация(или как это называется).

Сообщить модератору | | IP: Записан
Сообщение: 156987

Старое сообщение 22-07-2016 06:51
- За что?
thambs
мразь конченная

Дата регистрации: Mar 2006
Проживает: -
Сообщений: 6417

Рейтинг



ComradeAndrew
По смыслу получается, что функция принимает аргументы по значению (т.е. копирует их), а потом ещё раз копирует внутрь массива int dummy[]? Можно ли добиться поведения аналогичного передаче по ссылке?
И ещё вопрос -- а можно сделать количество однотипных аргументов параметром шаблона?

__________________
http://www.moddb.com/mods/monorail-quest

Сообщить модератору | | IP: Записан
Сообщение: 157015

Старое сообщение 22-07-2016 16:17
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 15:19. Новая тема    Ответить
Страницы (3): [1] 2 3 »   Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Наш форум > Технические вопросы > с++: опять запутался в трёх соснах.
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

На основе vBulletin
Авторское право © 2000 - 2002, Jelsoft Enterprises Limited.
Дизайн и программирование: Crystice Softworks © 2005 - 2024