【问题标题】:Incomplete type using typedef function pointer使用 typedef 函数指针的不完整类型
【发布时间】:2011-09-10 14:20:09
【问题描述】:

我有一个定义数据接收器接口的抽象基类。数据接收器的具体实现是通过工厂获得的。为了整理代码,我为工厂方法创建了一个 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&lt;get_new_data_sink_function_type&gt; getNewDataSinkFunction_;
在路上的某个地方,我得到:
error: field 'getNewDataSinkFunction_' has incomplete type
如果我改为声明:
boost::function&lt;std::auto_ptr&lt;DataSink&gt;(std::string)&gt; getNewDataSinkFunction_;
...一切都很好。

我意识到 DataSink 是一个不完整的类型,因为它是抽象的,但是由于 std::auto_ptr 我使用了引用语义,所以应该没问题,对吧?无论如何,这并不能解释为什么 typedef 失败并且 typedef 定义的剪切和粘贴成功。这是 boost::function 的怪癖吗?

编译器是 gcc 4.3.3。任何见解都非常感谢。

【问题讨论】:

  • const 参数上的 const 限定符确实不需要,删除它们会使代码更适合问题(没有水平滚动条)。
  • 你是对的,因为它们是按值传递的。 const 我知道的限定论点是 const 几乎已经成为一种反射...有点过分热心,那里:)

标签: c++ typedef auto-ptr boost-function incomplete-type


【解决方案1】:

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* 与之前的函数类型指针相同。

【讨论】:

  • 啊,有道理。我实际上不知道你可以 typedef 一个这样的函数签名;我以为您仅限于函数指针。我进一步混淆了自己,认为这没关系,因为 boost::function 对象可以分配给具有兼容签名的常规函数​​指针......为什么我认为这意味着模板参数可以被类似地替换我只能归咎于暂时的精神错乱...
猜你喜欢
  • 1970-01-01
  • 2013-09-09
  • 2017-02-25
  • 2016-09-05
  • 2015-09-04
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-06
相关资源
最近更新 更多