HLFX.Ru Forum Страницы (3): [1] 2 3 »
Показать все 123 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- нубовопросы по c++ (https://hlfx.ru/forum/showthread.php?threadid=5083)


Отправлено thambs 20-12-2017 в 19:37:

нубовопросы по c++

Неожиданно, возник вопрос про конструкторы по умолчанию. Например, есть структура

C++ Source Code:
1
struct foo{
2
  foo(){}
3
  foo(int...){}
4
};
5
int main () {
6
  foo x;
7
  foo y();
8
  foo z(1);
9
  cout<<typeid(x).name()<<endl;
10
  cout<<typeid(y).name()<<endl;
11
  cout<<typeid(z).name()<<endl;
12
  return 0;

На выходе имеем
Цитата:
3foo
F3foovE
3foo

или после с++filt
Цитата:
foo
foo ()
foo

Почему записи "foo x" и "foo x()" не эквивалентны и что за такой тип "foo ()"?

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


Отправлено XaeroX 21-12-2017 в 04:13:

Тип foo() - это функция, возвращающая foo и не принимающая никаких аргументов. Ты же сам её объявил, смотри:

C++ Source Code:
foo x;  // создание экземпляра класса foo с вызовом конструктора по умолчанию
foo y();  // объявление функции y, которая возвращает foo
foo z(1);  // создание экземпляра класса foo с вызовом конструктора foo(int)

Пустые круглые скобки нельзя использовать для вызова конструктора по умолчанию при создании объекта. Тут возникает двусмысленность - и компилятор строго по стандарту её разрешает. Если процитировать стандарт своими словами - то примерно так: "всё, что может быть объявлением функции, должно быть объявлением функции".

__________________

xaerox on Vivino


Отправлено thambs 21-12-2017 в 08:31:

>это функция
действительно. что-то сразу не распарсил.

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


Отправлено ComradeAndrew 21-12-2017 в 18:56:

C++ Source Code:
foo y();  // объявление функции y, которая возвращает foo

Вот ведь. Никогда об этом не задумывался. Только сейчас дошло. Спасибо


Отправлено Дядя Миша 21-12-2017 в 19:42:

А в новых стандартах C++ вот так

C++ Source Code:
std::vector< std::pair< vec_t, int >> foo;

уже можно песать или до сих пор нельзя?

__________________
My Projects: download page

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

Цитата:

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


Отправлено nemyax 21-12-2017 в 19:49:

Дядя Миша
В смысле STL-контейнер в STL-контейнере? Я юзал и мысли не было, что так нельзя. Студия 2015 хавала.

C++ Source Code:
std::map<HCP*, std::set<HCP*>> slu;


Отправлено Дядя Миша 21-12-2017 в 19:52:

Цитата:
nemyax писал:
В смысле STL-контейнер в STL-контейнере?

нет. Ну Ксер поймет

__________________
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-12-2017 в 21:23:

>foo y(); // объявление функции y, которая возвращает foo
А не, всё равно не распарсил, это же nested-функция получается а они в стандарте запрещены.

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


Отправлено nemyax 21-12-2017 в 21:32:

thambs
Объявить дадут, а определить нет.


Отправлено XaeroX 22-12-2017 в 04:58:

Да, объявлять функции внутри функций вполне можно.
Вот тебе конкретный пример, где это необходимо:

C++ Source Code:
1
class Bar
2
{
3
public:
4
  Bar() = default;
5
  void Foo();
6
};
7
 
8
void Bar::Foo()
9
{
10
  Bar foo(); // <---- это не создание объекта класса Bar, но эта строка нужна!
11
  foo();
12
  std::cout << "Bar";
13
}
14
 
15
Bar foo()
16
{
17
  std::cout << "Foo";
18
  return Bar();
19
}
20
 
21
int main(int argc, char *argv[])
22
{
23
  Bar bar;
24
  bar.Foo();
25
}


Добавлено 22-12-2017 в 11:58:

Цитата:
Дядя Миша писал:
уже можно песать или до сих пор нельзя?

Да хоть так:
C++ Source Code:
std::vector<std::vector<std::vector<std::pair<int,int>>>> v;

__________________

xaerox on Vivino


Отправлено Дядя Миша 22-12-2017 в 14:32:

Цитата:
XaeroX писал:
Да хоть так:

И компилятор больше не посчитает это битовым сдвигом?

__________________
My Projects: download page

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

Цитата:

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


Отправлено XaeroX 22-12-2017 в 17:27:

Дядя Миша
Ошибка была только в компиляторе MSVC, она давно исправлена, да.

__________________

xaerox on Vivino


Отправлено Дядя Миша 22-12-2017 в 17:49:

XaeroX ну что же. Для шестой студии статьи Борескова всё еще актуальны

__________________
My Projects: download page

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

Цитата:

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


Отправлено XaeroX 22-12-2017 в 18:31:

Дядя Миша
Шестая студия - это легенда, о которой рассказывают седые старики. Ну примерно как о том, как видели живого нациста.

__________________

xaerox on Vivino


Отправлено Дядя Миша 22-12-2017 в 19:15:

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 23-12-2017 в 00:58:

XaeroX
Т.е. функцию вроде-как определили в локальном неймспэйсе класса, а она вылезла в глобальный? Вот этот момент какой-то странный, хоть и компилируется. Это точно не UB?

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


Отправлено XaeroX 23-12-2017 в 05:57:

thambs
Функция определена в глобальном неймспейсе.
Кажется, ты путаешь объявление и определение.

__________________

xaerox on Vivino


Отправлено nemyax 23-12-2017 в 08:15:

XaeroX
Такой вызов — единственная осмысленная вещь, которую можно сделать с этой объявленной функцией?

Кстати, в гецеце же вроде можно включить расширение, которое даёт вложенные функции.


Отправлено XaeroX 23-12-2017 в 09:46:

Цитата:
nemyax писал:
Такой вызов — единственная осмысленная вещь, которую можно сделать с этой объявленной функцией?

А что ещё можно сделать с функцией, кроме как вызвать?
Ну можешь адрес взять.

Цитата:
nemyax писал:
Кстати, в гецеце же вроде можно включить расширение, которое даёт вложенные функции.

Кошмар какой.
Это не нужно, т.к. есть лямбды.

__________________

xaerox on Vivino


Отправлено thambs 23-12-2017 в 11:48:

XaeroX
Так объявление в неймспэйсе класса, а определение в глобальном, вот это мне странно. Так ведь можно и в другом классе такую же функцию объявить и будет путанница или нет?

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


Отправлено a1batross 23-12-2017 в 12:12:

XaeroX даже если лябмд нет, можно объявлять, например, структуру со статическими методами прямо в теле. Но из двух кошмаров и лямбд, всё же лучше выбирать лямбды.


Отправлено Government-Man 23-12-2017 в 12:26:

Цитата:
thambs писал:
Так ведь можно и в другом классе такую же функцию объявить и будет путанница или нет?


Если ты будешь вызывать ее из этого же класса, то будет вызываться функция из класса.


Отправлено XaeroX 23-12-2017 в 12:30:

Цитата:
a1batross писал:
даже если лябмд нет, можно объявлять, например, структуру со статическими методами прямо в теле.

Ну можно, конечно, мы в детстве так развлекались.
Но это формально не вложенная функция.
Цитата:
thambs писал:
Так ведь можно и в другом классе такую же функцию объявить и будет путанница или нет?

А ты поэкспериментируй с typeid и увидишь, что у них разные сигнатуры будут.
Путаница может быть только с namespace. И здесь у плюсов весьма и весьма запутанные правила. Но они существуют.

__________________

xaerox on Vivino


Отправлено Дядя Миша 23-12-2017 в 13:45:

Цитата:
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 10-05-2018 в 16:19:

А вот ещё вопрос про наследование возник внезапно.
Например, у меня есть базовый шаблонный класс

C++ Source Code:
1
template <typename t, size_t n>
2
struct base{
3
  t*         data;
4
  size_t* shape;
5
base<t, dim>(t* data, size_t* shape):
6
  data(data), shape(shape){}
7
  ...
8
};
внутри которого определены всякие полезные методы.
Я хочу отнаследоваться от него, прилинковав указатель shape к массиву:
C++ Source Code:
1
template <typename t, size_t n>
2
struct derived: base<t, n>{
3
  size_t _shape[n];
4
  derived<t, dim>(){
5
    this->data   = nullptr; //кстати, почему здесь нужно обращаться к this?
6
    this->shape  = _shape;
7
  };
8
  ...
9
};
, однако, хотелось бы избавиться от лишнего присваивания и в явном виде "подменить" указатель на массив. Если я просто объявлю size_t shape[n], то в результате получу ещё одно поле с тем же именем, чего мне не нужно. Как сделать правильно?

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


Отправлено ComradeAndrew 10-05-2018 в 16:38:

Цитата:
thambs писал:
хотелось бы избавиться от лишнего присваивания и в явном виде "подменить" указатель на массив

Прямо переопределить не получится
https://stackoverflow.com/a/19290950/4109062


Отправлено thambs 10-05-2018 в 16:54:

ComradeAndrew
Хмм, а как тогда лучше перестроить иерархию классов?
Конкретно, у меня такой вариант морды, для доступа к многомерному массиву:

code:
template <typename t, size_t dim> struct carray_base{ t* data; size_t* offset; size_t* shape; carray_base<t, dim>(t* data, size_t* shape, size_t* offset): data(data), shape(shape), offset(offset) {} inline size_t size(void)const{ return shape[0]*offset[0]; } template <typename num, size_t d = dim, typename enable_if<(d > 1), size_t>::type = 0> inline carray_base<t, dim-1> operator [] (num i){ return carray_base<t, dim-1>(data + (size_t)i*offset[0], shape+1, offset+1); } template <typename num, size_t d = dim, typename enable_if<(d == 1), size_t>::type = 0> inline t& operator [] (num i) { return data[(size_t)i]; } };

Предполагается, что место под данные заранее аллокировано (где угодно, хоть на стеке, хоть в куче, хоть на gpu). Что бы это можно было удобно использовать и копировать, хочется сделать производный класс, который и сам обращается с внешним аллокатором, но вот аллокатить ещё и место под служебные данные совсем не хочется, логично было бы хранить offset и shape прямо в классе. Вот и думаю как лучше сделать.

ps: тег [/сср] корябает отступы

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


Отправлено thambs 11-05-2018 в 17:21:

Ага, разобрался. Сделал так:

code:
template <typename t, size_t dim, bool proxy> struct carray_base{ static_assert(dim>0, ""); typedef typename conditional<proxy, size_t*, size_t[dim]>::type id; t* data; id offset; id shape; ... }; template <typename t, size_t dim> struct carray: carray_base<t, dim, false>{ ... };

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


Отправлено Дядя Миша 11-05-2018 в 21:35:

Как вы эти шаблоны делаете, я их боюсь до ужаса.

__________________
My Projects: download page

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

Цитата:

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


Отправлено XaeroX 12-05-2018 в 08:04:

Дядя Миша
Ну шаблоны - скорее исключение, чем правило. Их обычно не рекомендуют использовать там, где можно без них обойтись (то есть в 99% случаев). Для меня на работе протащить шаблон в master - это всегда праздник.

__________________

xaerox on Vivino


Отправлено thambs 16-05-2018 в 09:17:

Ага, а в 17м стандарте можно наконец-то сделать по человечески:

code:
typedef typename conditional <(dim>1), carray_base<t, dim-1, true>, t&>::type out; template <typename num> //c++17 inline out operator [] (const num& i){ if constexpr (dim>1){ return out(data + (size_t)i*offset[0], shape+1, offset+1); } else { return data[(size_t)i]; } }

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

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


Отправлено Дядя Миша 16-05-2018 в 11:13:

Цитата:
XaeroX писал:
Для меня на работе протащить шаблон в master - это всегда праздник.



Добавлено 16-05-2018 в 14:13:

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

Я не знаю, что по этому поводу думает Ксер, но у меня сложилось мнение, что парадигма С++ идеально ложится только на две вещи - всевозможные окошки-менюшки и как ни странно энтити из халфы-кваки, да и вообще игровые объекты. Потому что там все эти принципы наследования очень кстати. А в повседневности С++ годится только для АТД.

__________________
My Projects: download page

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

Цитата:

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


Отправлено XaeroX 16-05-2018 в 15:01:

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

Потому же, почему так поздно вернули Крым.

__________________

xaerox on Vivino


Отправлено thambs 05-06-2018 в 16:06:

Извиняюсь ещё раз за поднятие темы, но есть ли разница между приведением типов

code:
(int)(x)
и (вызовом конструктора?)
code:
int(x)
?

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


Отправлено a1batross 05-06-2018 в 16:37:

thambs никакой.


Отправлено Government-Man 05-06-2018 в 16:43:

Цитата:
thambs писал:
есть ли разница


Формально - это совершенно разные вещи. И вроде даже есть случаи, когда это имеет значение.


Отправлено XaeroX 05-06-2018 в 17:22:

Цитата:
a1batross писал:
thambs никакой.

+1

Цитата:
The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name: unsigned int(expression) or int*(expression) are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.

http://en.cppreference.com/w/cpp/language/explicit_cast

P.S.: не надо так писать. Используй static_cast.

__________________

xaerox on Vivino


Отправлено Дядя Миша 05-06-2018 в 18:47:

Цитата:
Government-Man писал:
И вроде даже есть случаи, когда это имеет значение.

А что в новых крестах можно атомарные типы перегружать?

__________________
My Projects: download page

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

Цитата:

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


Отправлено Дядя Миша 06-06-2018 в 10:23:

Вот и у меня созрел вопрос по С++. Атомарный тип half в язык добавят когда-нибудь уже наконец.

__________________
My Projects: download page

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

Цитата:

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


Отправлено ComradeAndrew 06-06-2018 в 11:37:

Дядя Миша
Вряд ли. Минимальный размер выделяемой памяти - байт. А битовые поля и так есть https://en.cppreference.com/w/cpp/language/bit_field
А насчет "атомарности", мне кажется тут некая путаница возникла. Фундаментальные типы не являются атомарными - https://stackoverflow.com/questions...al-types-atomic


Отправлено Дядя Миша 06-06-2018 в 11:57:

ComradeAndrew ты точно понял мой вопрос?

Добавлено 06-06-2018 в 14:57:

half это вещественное с половинной точностью, два байта занимает.

__________________
My Projects: download page

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

Цитата:

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


Отправлено ComradeAndrew 06-06-2018 в 12:04:

Цитата:
Дядя Миша писал:
half это вещественное с половинной точностью, два байта занимает.

Ах, вот оно что. Да, не про то подумал, извиняюсь.
К сожалению на счет этого ничего не могу сказать.


Временная зона GMT. Текущее время 06:53. Страницы (3): [1] 2 3 »
Показать все 123 сообщений этой темы на одной странице

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