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

с учетом следующего кода:

#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 Ответ

0 голосов
/ 27 июня 2018

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

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

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

f.reset(ff);

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

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

f.reset(ff, fclose);
...