Запрашивает ссылку на shared_ptr для базового element_type

#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