#c
#c
Вопрос:
У меня очень дикий тип и shared_ptr, указывающий на него. Я инициализирую этот общий ptr в nullptr. Затем я хотел бы создать соответствующий объект и предоставить дикий тип в качестве параметра make_shared . Я хотел бы задать указатель на этот тип.
std::shared_ptr<cl::make_kernel<cl::Bufferamp;,
cl_double16amp;,
cl_double3amp;,
cl_double3amp;,
cl_int3amp;,
cl_double3amp;,
cl_double3amp;,
cl_int2amp;,
floatamp;>>
pointer = nullptr;
auto ptr = pointer;
ptr = std::make_shared<decltype(ptr)>::element_type>();
К сожалению, предыдущий код не изменяет значение самого указателя. Поэтому я хотел бы повысить абстракцию на один уровень выше, чтобы иметь
autoamp; ptr = pointer;
ptr = std::make_shared<decltype(ptr)::element_type>();//Fails
ptr = std::make_shared<std::remove_reference<decltype(ptr)>::element_type>();//Fails
ptr = std::make_shared<std::remove_reference<decltype(*ptr)>::type>;//Works but I doubt if this provides correct type when pointer==nullptr
Есть ли способ, как запросить ссылку на общий указатель для типа элемента общего указателя?
Вы убедили меня, что использование std::remove_reference<decltype(*ptr)::type> в порядке, при этом вычисляется время компиляции, а не время выполнения. Итак, все еще остается просто академический вопрос, есть ли способ, как задать эту ссылку на указатель напрямую https://godbolt.org/z/KT9oEM
Чтобы объяснить, почему у меня возник этот вопрос. Imagine pointer
является членом класса, и я хотел бы инициализировать его в методе, не вводя его element_type при вводе имени pointer
не более одного раза.
Комментарии:
1.
decltype(*ptr)
вычисляется во время компиляции, а не во время выполнения.2.
std::make_shared<decltype(a)::element_type>();
должно работать, что именно не работает?3. См . godbolt.org/z/KT9oEM куда я помещаю ошибки, которые я получил.
Ответ №1:
decltype(ptr)
будет типом shared_ptr
самого элемента, а не его типом элемента. Вы правильно используете decltype()
для разыменованного типа the shared_ptr
. Это будет оцениваться во время компиляции, а не во время выполнения, так nullptr
что это вообще не проблема:
std::shared_ptr<...> pointer = nullptr;
auto ptr = std::make_shared<std::remove_reference<decltype(*pointer)>::type>();
ОБНОВЛЕНИЕ: в вашем новом примере:
autoamp; ptr = pointer;
ptr = std::make_shared<std::remove_reference<decltype(ptr)>::element_type>();
std::remove_reference
сам по себе не имеет element_type
члена. Тип, из которого вы удаляете amp;
( shared_ptr<...>
from shared_ptr<...>amp;
), — это тип, в котором есть element_type
элемент. Вам нужно добавить ::type
after remove_reference<... >
для доступа к этому разрешенному типу, например:
std::remove_reference<decltype(ptr)>::type::element_type
Или, в C 14 и более поздних версиях, вы можете использовать std::remove_reference_t
вместо:
std::remove_reference_t<decltype(ptr)>::element_type
Комментарии:
1. Спасибо! На практике есть способ, как это сделать без каких-либо сомнений. Но мне все еще любопытно, почему я получаю сообщение об ошибке: ‘element_type’ не является членом ‘std:: remove_reference<std::shared_ptr<std::vector<int> >amp;>’ и если это возможно исправить без оператора *, см. godbolt.org/z/KT9oEM
2. Спасибо, это полностью отвечает на мой вопрос.
Ответ №2:
Вы создали указатель на новый «сумасшедший» объект, а не на существующий. Но вы использовали decltype для получения указателя того же типа. Т.Е. Теперь у вас есть 2 указателя и 2 объекта.
Вы могли бы сделать что-то вроде:
std::shared_ptr<std::remove_pointer/reference<decltype(...whatever...)>::type> new_pointer(old_pointer);
Этот псевдокод использует decltype для создания типа shared_ptr, но затем просто присваивает его существующему объекту.
Другой вариант, который вы, возможно, захотите попробовать, — это псевдоним для вашего «сумасшедшего» типа! — что-то вроде:
using crazy_type = cl::make_kernel<cl::Bufferamp;,
cl_double16amp;,
cl_double3amp;,
cl_double3amp;,
cl_int3amp;,
cl_double3amp;,
cl_double3amp;,
cl_int2amp;,
floatamp;>;
auto item = make_shared<crazy_type>();
Я не могу создать пример вашего точного кода, потому что у меня нет всех классов, но вот упрощенный пример: https://godbolt.org/z/MKo5dj
Комментарии:
1. Я объяснил, чего я пытаюсь достичь в последнем абзаце вопроса, выделенном курсивом. Смотрите также godbolt.org/z/KT9oEM