如何将"extern template"与同一类中的模板成员使用的嵌套类一起使用?
How to use "extern template" with a nested class which is used by a templated member in the same class?
首先,一些上下文:我试图以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>"
由于"extern template"不能在类声明中使用,我无法编写
#include "pimpl_h.h"
class widget {
class impl;
extern template pimpl<impl>;
pimpl<impl> m;
// ...
};
我想不出其他办法了。我的问题是:
IntelliSense接受我的代码是错误的,编译器是正确的吗?或者只是巧合,VC++编译了这个,而它不是有效的C++?
如果我的解决方案不是有效的C++,我有什么替代方案?
我想这是我自己想出来的。在§14.7.2.11中,标准规定
如果一个实体是显式实例化声明和显式实例化的主体实例化定义在同一翻译单元中,定义应遵循公告
这可能就是IntelliSense所指的。这就是我注意到错误消息说"…不能遵循显式实例化…"的地方。显然,任何地方都没有显式实例化,只有 一个实体,它是显式实例化声明的主体,也是使用的方式会导致翻译单位应该是一个明确的实例化定义的主题-程序中的位置;否则程序格式不正确,不需要进行诊断。 其不需要(潜在的)隐式实例化和显式实例化声明的任何特定顺序。 在这一点上,我也意识到我的解决方案实际上对我最初的问题来说是过度的。我不想阻止widget
的类定义中的隐式pimpl<impl>
的模板类声明和定义的隐式实例化,而只是pimpl_impl.h
中的模板类extern template pimpl<impl>
抑制了两者,这解决了我的问题,但做得更多。解决方案是用extern template
声明pimpl<impl>
的实际成员,然后显式实例化它们。
- C++ 如何将关键字"friend"与两个类的成员函数一起使用 相互包含
- 与引用一起使用的列表,在用作成员时更改行为
- 在 c++ 中将模板与类一起使用时,类成员函数的答案错误?
- 将 PIMPL 习惯用法与成员函数模板一起使用(无需预先了解所有可能的数据类型)
- 如何将两个类成员函数与同一类中的另一个函数一起添加
- 如何将此指针与指向成员函数的指针一起使用
- 将指令与模板化成员函数一起使用
- 常量变量初始化仅与成员初始化列表一起工作
- 与const成员一起安排新的和班级的分配
- GCC 中的编译器错误,但在将 decltype 与具有尾随返回类型语法的模板化成员函数一起使用时没有 clang
- 将异步与多态成员函数一起使用
- 将GSL与C 一起使用时,如何避免静态成员函数
- boost :: Spirit :: Qi-与语法结构中的实例成员一起工作
- 如何将序列化方法添加到作为Windows数据结构的类成员中,以便在C++中与boost序列化一起使用
- 为什么点运算符(.)可以与私有类成员/方法一起使用
- 将在一行中声明的成员记录在一起,而不创建组
- 获取指向成员std::string::size的指针无法与libc++链接,但可以与libstdc++一起使用
- 如何将尾随返回类型与模板化类成员一起使用
- 与私人成员一起上课.这个代码出了什么问题
- 将 decltype 与虚拟成员函数指针一起使用