Неполный тип с использованием указателя функции typedef - PullRequest
2 голосов
/ 08 июня 2011

У меня есть абстрактный базовый класс, который определяет интерфейс для приемников данных. Конкретные реализации приемников данных приобретаются через фабрики. Чтобы привести в порядок код, я создал typedef для фабричного метода, который возвращает новые объекты DataSink из абстрактного базового класса DataSink.

#include <memory>
#include <string>

class DataSink
{
    public:
            DataSink() { }
            virtual ~DataSink() { }
            void Open(const std::string path)
            {
                    InternalOpen(path);
            }
            bool IsOpen()
            {
                    return InternalIsOpen();
            }
            void Write(const uint8_t* data, const size_t offset, const size_t size)
            {
                    InternalWrite(data, offset, size);
            }
            void Close()
            {
                    InternalClose();
            }

    protected:
            virtual void InternalOpen(const std::string path) = 0;
            virtual bool InternalIsOpen() = 0;
            virtual void InternalWrite(const uint8_t* data, const size_t offset, const size_t size) = 0;
            virtual void InternalClose() = 0;
};
typedef std::auto_ptr<DataSink>(*get_new_data_sink_function_type)(std::string);

Если я тогда попытаюсь объявить:
boost::function<get_new_data_sink_function_type> getNewDataSinkFunction_;
где-то вниз по дороге я получаю:
error: field 'getNewDataSinkFunction_' has incomplete type
Если я вместо этого объявлю:
boost::function<std::auto_ptr<DataSink>(std::string)> getNewDataSinkFunction_;
... все хорошо.

Я понимаю, что DataSink является неполным типом, потому что он абстрактный, а потому что я использую ссылочную семантику из-за std :: auto_ptr, это должно быть хорошо, верно? В любом случае, это не объясняет, почему typedef терпит неудачу, а вырезание и вставка определения typedef завершается успешно. Это причуда с boost :: function?

Компилятор gcc 4.3.3. Любое понимание высоко ценится.

1 Ответ

3 голосов
/ 08 июня 2011

get_new_data_sink_function_type не тип функции, а тип указателя на функцию.boost::function требуется тип функции (или подпись).

Кроме того, абстрактный класс не обязательно должен быть неполным типом (и он не находится на сайте вашего typedef).Часть предупреждения «неполный тип», вероятно, проистекает из того факта, что boost::function возможно записывается так:

template<typename Sig>
class function; // Not defined!

template<typename Ret, typename Arg>
class function<Ret(Arg)> {
    // ...
};

// Various other specializations

, что означает, что когда boost::function создается с нефункциональным типом, какв вашем случае специализация не совпадает и базовый шаблон выбран.Так как он не определен, это неполный тип.


Самое простое исправление, которое вы можете сделать, - это сделать ваш typedef реальным типом функции, что сделает его имя больше не вводящим в заблуждение:

typedef std::auto_ptr<DataSink> get_new_data_sink_function_type(std::string);

Обратите внимание, что при этом get_new_data_sink_function_type* будет таким же указателем на тип функции, как и раньше.

...