Пользовательский модуль удаления unique_ptr создает предупреждения «функция не используется» в коде объекта и ошибку при связывании

Я создаю объектный файл для моей более крупной программы. В этой программе я использую тип unique_ptr с определенным настраиваемым средством удаления. Итак, я компилирую свой файл так:

g++ -std=c++20 tmp.cpp -c -Wall

Код выглядит следующим образом:

#include <memory>

using specialptr = std::unique_ptr<int, decltype([](int *f) {
                     delete f;
                   })>;

specialptr fun(){ 
  return specialptr{new int};
}

Это генерирует это предупреждение:

 tmp.cpp:12:12: warning: ‘specialptr fun()’ defined but not used [-Wunused-function]
   12 | specialptr fun(){ return specialptr{new int};}
      |  

Когда я связываю этот объектный файл с main.cpp, который вызывает функцию, я получаю следующую ошибку:

In file included from main.cpp:1:
tmp.h:19:12: warning: ‘specialptr fun()’ used but never defined
   19 | specialptr fun();
      |            ^~~
/usr/bin/ld: /tmp/ccnuTTGC.o: in function `main':
main.cpp:(.text+0x4c): undefined reference to `fun()'
collect2: error: ld returned 1 exit status

Что здесь происходит? Мой код работает, когда я меняю возвращаемое значение с unique_ptr на обычный указатель. Но интуитивно я определил тип и функцию и сделал объявление в заголовочном файле.

g++ — это версия: g++ (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

decltype лямбды отличается для каждой единицы перевода.

Вместо этого вы можете сделать что-то вроде:

struct specialptr_deleter {
  void operator()(int *f) const {
    delete f;
  }
};

using specialptr = std::unique_ptr<int, specialptr_deleter>;

specialptr fun(){ 
  return specialptr{new int};
}

Ах да ладно. Но это означало бы ставить Deleter каждый раз, когда я использую specialptr, верно? Это оставляет открытой возможность того, что я забуду дать ему правильное удаление. ммч

Tarick Welling 09.01.2023 19:56

@TarickWelling На самом деле вы не можете забыть указать удаление с таким типом. В этом случае компилятор его не скомпилирует. Но вы можете случайно или специально создать указатели с разными реализациями удаления.

sklott 09.01.2023 20:03

В этом случае вы можете использовать структуру. Смотрите мой обновленный ответ

Etienne Laurin 09.01.2023 20:04

Вы можете использовать тип объекта в качестве удаления. В этом случае вам не нужно устанавливать его каждый раз, когда вы создаете std::unique_ptr.

#include <memory>
#include <iostream>

struct MyDeleter {
    void operator()(int *f) {
        std::cout << "Deleter called";
        delete f;
    }
};

using specialptr = std::unique_ptr<int, MyDeleter>;

specialptr fun(){ 
  return specialptr{new int};
}

int main()
{
    auto x = fun();
}

Другие вопросы по теме