Как я могу исправить следующую ошибку "нет совпадения для вызова '(std:: tr1:: shared_ptr<_iobuf *>) (FILE * &)'"

Учитывая следующий код:

#include <cstdio>

#include <tr1/memory>  // "tr1" is in order to fix it at Eclipse!
using std::tr1::shared_ptr;  

class CannotOpenFileException: public std::exception {
};

class FileOutput  {
    shared_ptr<FILE*> f;
public:
    FileOutput(const char* filename) {
        FILE* ff = fopen(filename, "w");
        if (ff == nullptr) {
            throw CannotOpenFileException();
        }
        f(ff); //****error
    }
};

Я получаю следующую ошибку:

нет совпадения для вызова '(std:: tr1:: shared_ptr<_iobuf *>) (FILE * &)'

Почему я получаю эту ошибку и как ее исправить?

Примечание: я хочу использовать функции языка C (на C++) для проверки чего-либо, поэтому нет необходимости комментировать это.

1 ответ

Решение

У вас есть две проблемы:

Во-первых, аргумент шаблона - это класс, на который указывают. Так что если вы хотите указатель на Foo тогда шаблон должен быть Foo, В вашем случае вы говорите, что f это указатель на указатель на FILE, Итак, первое, что вам нужно сделать, это сделать f указатель на FILE предоставив тип FILE при определении f,

Вторая проблема заключается в том, что переменная f это не функция, которую вы можете вызвать, это объект. Вам нужно использовать объекты reset функция:

f.reset(ff);

Теперь, что касается первой проблемы, ее решение приводит к другой проблеме. Проблема возникает из-за удаления по умолчанию для shared_ptr делает то, на что это похоже: он пытается delete содержащийся указатель. Это невозможно по нескольким причинам (например, FILE непрозрачный тип данных, и указатель не был создан с new).

Это решается просто с помощью fclose выполнять функцию удалителя и передавать его вместе с reset вызов:

f.reset(ff, fclose);
Другие вопросы по тегам