【发布时间】:2014-06-13 03:11:03
【问题描述】:
首先,一些上下文:我正在尝试以 Herb Sutter 在他的GotW #101 的解决方案中提出的方式使用 Pimpl 成语。这在头文件中看起来像这样:
#include "pimpl_h.h"
class widget {
class impl;
pimpl<impl> m;
// ...
};
实现如下所示:
#include "pimpl_impl.h"
class widget::impl {
// ...
};
当使用此技术的类使用另一个 Pimpl 类进行自己的实现时,就会出现我试图解决的问题。它包含“pimpl_impl.h”,因此编译器(在我的情况下为 VC++ 2013)获得了另一个类的 pimpl <impl> 的具体模板的知识,并尝试隐式实例化它,这当然会导致编译错误。不知道那个类的实现。
为了解决这个问题,我在标头中使用了 C++ 11 的新“外部模板”功能:
#include "pimpl_h.h"
class widget {
class impl;
pimpl<impl> m;
// ...
};
extern template pimpl<widget::impl>;
这应该保证只有我在提供widget::impl 实现的编译单元中的显式实例化会导致实际实例化。这编译没有问题,但 IntelliSense 显示错误:
Error: 'extern template' cannot follow explicit instantiation of class "pimpl<widget::impl>"
由于不能在类声明中使用“外部模板”,所以我不能写
#include "pimpl_h.h"
class widget {
class impl;
extern template pimpl<impl>;
pimpl<impl> m;
// ...
};
我想不出任何其他方式。我的问题是:
在接受我的代码时 IntelliSense 是否错误而编译器是否正确?还是 VC++ 编译它而它不是有效的 C++ 只是巧合?
如果我的解决方案不是有效的 C++,我有什么替代方案?
【问题讨论】: