1

голосов
1

ответ
59

Просмотры

Правильный способ распределения массива вместе с его владельцем

Я пытаюсь динамически выделять массив общего типа наряду с такими примитивами блока управления. Возьмите это как образцовый код этого «блока управления»: шаблон структуру my_array {T * обры; без знака размера; }; Для того, чтобы избежать нескольких распределений я пытаюсь вызвать выделение нового только один раз. Это код, который я придумал: шаблон my_array * alloc_new_array (без знака размер) {неподписанных align_mismatch = SizeOf (my_array)% alignof (my_array); без знака ARRAY_SIZE = размер * SizeOf (Т); без знака struct_size = SizeOf (my_array) + align_mismatch? alignof (my_array) - align_mismatch: 0; символ * память = новый символ [ARRAY_SIZE + struct_size]; my_array * обр = новый (память) my_array; arr-> обр = новый (память + struct_size) Т [размер]; arr-> размер = размер; вернуться обр; } Что меня беспокоит это: Правильность - Я думаю, что я позаботилась о STRUCT дополнения, но может быть что-то мне не хватает. Разве я считаю это правильно, и он будет работать должным образом, независимо от платформы? Соответствие стандартам - не я нарушу какое-либо правило C ++ и вызвать UB? Я знаю, что я делаю какой-то указатель магии здесь, и я не уверен, если все полностью легально
bartop
1

голосов
1

ответ
41

Просмотры

Чрезмерная функция завода по RValue и Lvalue ссылки - эффективная инициализация

Рассмотрим следующий фрагмент кода: STRUCT б {// медленно копировать, быстро перемещать данные}; Шаблон структура с {с (Т &&, && Ь) {} с (Т &&, Const б &) {} // я должен обеспечить как? }; Шаблон автоматического make_c (T && т, б && _) {возвращение с (станд :: вперед (т), станд :: ход (_)); } Шаблон автоматического make_c (Т && т, Const б & _) {возвращение с (станд :: вперед (т), _); } // я должен сделать как make_c перегрузки? Как говорят комментарии - это нужно сделать как RValue и именующее make_ функции / конструкторами или есть способ избежать дублирования кода. Я должен сказать, что я чувствую себя как-то неудобно с копированием большую часть кода функции только удаление функции перемещения. PS: Это синтетический пример - добавление дополнительных шаблонов аргумент (ы) невозможно из-за MSVC проблем компилятора с оператором | перегрузка.
bartop
19

голосов
4

ответ
1.3k

Просмотры

Есть ли статические иметь значение для константной локальной переменной?

Представьте себе следующую декларацию: недействительным Foo () {сопз обр станд :: массив = {/ * много различных значений * /}; // делать вещи} а второй: пустое Foo () {статический обр Const станд :: массив = {/ * много различных значений * /}; // делать вещи} Каковы возможные различия в производительности между этими двумя, если таковые имеются? И есть ли какая-либо опасность, связанная с каким-либо из этих решений?
bartop
3

голосов
0

ответ
32

Просмотры

Есть ли статические делает разницу для сопзЬ локальной переменной?

Представьте себе следующее заявление: пустое Foo () {сопз обр станд :: массив = {/ * много различных значений * /}; // делать вещи} а второй: пустое Foo () {статический обр Const станд :: массив = {/ * много различных значений * /}; // делать вещи} Каковы возможные различия в производительности между этими двумя, если таковые имеются? И есть ли какая-либо опасность, связанная с каким-либо из этих решений?
bartop
3

голосов
1

ответ
73

Просмотры

Почему двойное двоеточие в шаблоне аргументы работают?

Отвечая на один из вопросов, SO я наткнулся на код, как это: шаблон недействительным Foo (); Шаблон аннулируются Foo () {} Он был представлен в качестве кода, специализирующимся шаблонной функции Foo, которая не является правильным, но это не моя проблема. Я хотел бы знать, почему компилятор позволяет, как это строительные фермы: класс T :: value_type в параметре шаблона. Я имею в виду, что это довольно очевидно, не так, я не могу придумать какие-либо ситуации, оператор сферы может быть частью имени аргумента (либо шаблон или функция). И поэтому у меня есть два qestions: Допускает ли стандарт это или это обозревает в компиляторах? Если стандарт позволяет, почему это так? Есть ли прецеденты?
bartop
3

голосов
2

ответ
201

Просмотры

Decltype отливать оператор в Visual Studio

Рассмотрим следующий пример кода: #include шаблон структуры lazy_caller {lazy_caller (T && один, U && два): m_one (один), m_two (два) {} оператор decltype (станд :: макс (Т (), U ())) () сопзЬ {вернуть зЬй :: макс (m_one, m_two); } Т m_one; U m_two; }; INT основных () {lazy_caller вызывающего абонента (1, 2); Int я = вызывающий абонент; возвращать 0; } Как вы можете себе представить, что в реальном коде я хотел сделать более сложный тип дедукции, чтобы создать соответствующий оператор преобразования. В любом случае - этот код не компилируется в VS2017 (и я думаю, то же самое с более ранними) - и поэтому я хотел бы спросить, есть ли какое-либо решение этой проблемы? Я уже пробовал: оператор авто () Const Это также приводит к ошибкам компиляции, как: source_file.cpp (8): C2833 ошибки: «оператор-функция в стиле» бросание не является признанным оператором или типа Существует ли какое-либо решение этой проблемы с MSVC? Поскольку НКУ не имеет проблем с ни оператора, ни автоматического оператора decltype (..).
bartop
3

голосов
0

ответ
135

Просмотры

Atomics и нити голодание

У меня есть вопрос, касающийся как C ++ стандарт и в более общем компьютерную архитектуру. Представьте себе следующий фрагмент кода: #include #include зЬй :: атомное {0}; INT основных () {станд :: поток t1 ([& а] () {Int = 1; INT ао = a.load (), в то время (a.compare_exchange_weak (ао, я));!}), t2 ([ & а] () {INT I = 1; INT ао = a.load (), в то время (a.compare_exchange_weak (ао, I));}); t1.join (); t2.join (); возвращать 0; } У меня есть два вопроса: Может ли это в соответствии со стандартом, в теории приводит к зависанию? Во-вторых, это может на практике на x86 архитектуре приводят к голоданию? Могу ли я рассчитывать на это или нет?
bartop
2

голосов
1

ответ
66

Просмотры

Multi inheritance with template interface

Consider following piece of code: template.h template class templ{ public: virtual const int virtualMethod(const T *const) const = 0; } Base.h #include "template.h" class Der1; class Der2; class Base : public templ, public templ, public templ{ public: virtual ~Base(){} }; Der1.h #include "Base.h" class Der1 : public Base { public: virtual const int virtualMethod(const Base *const) const override; virtual const int virtualMethod(const Der1 *const) const override; virtual const int virtualMethod(const Der2 *const) const override; }; Der1.cpp #include "Der1.h" const int Der1::virtualMethod(const Base *const sth) const{ return sth->templ::virtualMethod(this);//does not work //how to fix it? } const int Der1::virtualMethod(const Der1 *const sth) const{ //do sth } const int Der1::virtualMethod(const Der2 *const sth) const{ //do sth } Class Der2 also inherits from Base and implements these three functions. For this code compiler gives me these messages: 'templ' is ambiguous ' Candidates are: templ() templ(const templ &) templ() templ(const templ &) templ() templ(const templ &) ' Function 'virtualMethod' could not be resolved Namespace member function 'virtualMethod' cannot be resolved. Type 'Der1' cannot be resolved. undefined reference to `templ::virtualMethod(Der1 const*) const' In general, the idea of the code was to implement double type dispatch. Although I think I know what causes problems, I have no idea how to solve it. So maybe you can help me.
bartop
2

голосов
1

ответ
36

Просмотры

Перемещение значений между lockfree списков

Фоновый Я пытаюсь разработать и внедрить безблокировочный HashMap, используя метод формирования цепочки в C ++. Каждая хеш-таблица ячейка должна содержать lockfree список. Чтобы включить изменение размера, моя структура данных должна содержать два массива - маленький, который всегда доступен и больше один для изменения размера, когда меньший один уже не достаточно. Когда больше создается один я хотел бы, чтобы данные, хранящиеся в маленькой, чтобы быть переданы в больший по одному, каждый раз, когда любой поток делает что-то со структурой данных (добавляет элемент, поиск или удаляет один). Когда все данные передаются, тем больший массив перемещаются на месте меньше, а второй один удаляются. Цикл повторяется каждый раз, когда массив должен быть расширен. Проблема Как уже упоминалось выше, каждый массив должен conatin списки в клетках. Я пытаюсь найти способ передать значение или узел из одного списка в другую lockfree таким образом, что бы сохранить значение видимые в любом (или оба) из списков. Это необходимо, чтобы гарантировать, что поиск в хэш-карта не даст пользователю ложные негативы. Так что мои вопросы: Является ли реализация списка таких lockfree возможно? Если да, то было бы общее понятие такого списка и «перемещение узла / значение» операция? Буду благодарен за любой псевдокод кода, C ++ или научная статья, описывающего его. операция? Буду благодарен за любой псевдокод кода, C ++ или научная статья, описывающего его. операция? Буду благодарен за любой псевдокод кода, C ++ или научная статья, описывающего его.
bartop
6

голосов
1

ответ
249

Просмотры

Template template argument causes compiler error under Clang but not GCC [duplicate]

This question already has an answer here: Template template parameter and default values [duplicate] 1 answer While helping with problem noted in too many template parameters in template template argument a question arose in my head: which compiler is right about the compilation in this case: template class Function { }; template struct Operator; template struct Operator {}; template struct Operator {}; using FunctionOperator = Function; int main(int argc, char * argv[]){ std::cout
bartop
15

голосов
2

ответ
417

Просмотры

reinterpret_cast ошибка или UB? [Дубликат]

Этот вопрос уже есть ответ здесь: Наблюдая странное поведение с «авто» и станд :: MinMax 1 ответ структурированными привязок с станд :: MINMAX и rvalues ​​2 ответов Рассмотрим следующий код: #include #include станд :: uintptr_t minPointer (недействительными * первый , недействительные * второй) {Const автоматических пары = станд :: MINMAX (reinterpret_cast (первый), reinterpret_cast (второй)); вернуться pair.first; } И сборка генерируется GCC8 с -O3 на https://godbolt.org/z/qWJuV_ для minPointer: minPointer (недействительных *, недействительная *): мы Rax, QWORD ПТР [RSP-8] RET, которая явно не делает что подразумевается под кодом создателя. Является ли этот код вызывает некоторые UB или это GCC (8) ошибка?
bartop
0

голосов
1

ответ
160

Просмотры

Универсальный способ преобразования правой рекурсии влево один

Я недавно работал с Flex и Bison. Я знаю, что обычно последний один не очень хорошо работает с правой рекурсией из-за размером стека. С другой стороны, большинство проблем грамматики легко решаемая с правой рекурсии. AFAIK существует универсальный алгоритм для изменения леворекурсивных к правой. Есть ли что работает противоположным образом? Вот простой пример: выражение: номер | выражение номер операции | Операция выражения openRound выражения closeRound | openRound выражение closeRound можно рассматривать номер и работу в качестве терминалов, так как они не имеют никакого отношения в примере.
bartop
1

голосов
1

ответ
74

Просмотры

MSVC ошибка с оператором |

Я работаю в библиотеке, что делает широкое использование шаблонов C ++. Во время написания я пришел к ситуации с кодом, как это (конечно, упрощенный): #include пространства имен нс {шаблонного класса с {}; класс а {}; шаблон класса б {общественности: шаблон автоматического отбора (A, B) {возвращение с {}; }}; Шаблон автоматического make_b (А) {возвращение Ь {}; } Шаблон автоматического оператора | (A _a, B _b) {возвращение _b.take (_a, _b); }} С использованием пространства имен нс; ИНТ основной () {а {} | make_b (а {}); возвращать 0; } При компиляции его с MSVC 19 (Visual Studio 2017) Я получаю следующий класс ошибок: /opt/compiler-explorer/windows/19.10.25017/lib/native/include/xlocale(314): предупреждение C4530: C ++ обработчик исключений используется , но семантика Отмотать не включена. Укажите / EHsc (28): ошибка C2228: Примечание: см ссылку на шаблон класса экземпляра «станд :: basic_string, станд :: распределителем>» компилируется Удаление с использованием пространства имен работает, но я не хочу, чтобы запретить его (почему я должен?). Есть ли решение? EDIT: Конечно, я тестировал код с GCC и Clang - компилирует под GCC от 4,9 и clang3 поэтому исключительно MSVC проблема. EDIT2: Я посмотрел на обнаруженные ошибки и, похоже, MSVC расширяет сферу перегруженного оператора | внутри стандартной библиотеки при использовании с использованием пространства имен. Я посмотрел на обнаруженные ошибки и, похоже, MSVC расширяет сферу перегруженного оператора | внутри стандартной библиотеки при использовании с использованием пространства имен. Я посмотрел на обнаруженные ошибки и, похоже, MSVC расширяет сферу перегруженного оператора | внутри стандартной библиотеки при использовании с использованием пространства имен.
bartop

Связанные вопросы