我的一位同事告诉我他用他的团队设计的一小块设计让我大开眼界。这是一种性状类,他们可以专门在一个非常分离的方式。未定义的模板方法技巧?
我很难理解它是如何工作的,我仍然不确定我的想法,所以我想我会在这里寻求帮助。
我们在这里讨论g ++,特别是3.4.2和4.3.2版本(它们似乎适用于两者)。
的想法是很简单:
1-定义接口
// interface.h
template <class T>
struct Interface
{
void foo(); // the method is not implemented, it could not work if it was
};
//
// I do not think it is necessary
// but they prefer free-standing methods with templates
// because of the automatic argument deduction
//
template <class T>
void foo(Interface<T>& interface) { interface.foo(); }
2-定义一个类,并且在源文件中专门接口这个类(定义它的方法)
// special.h
class Special {};
// special.cpp
#include "interface.h"
#include "special.h"
//
// Note that this specialization is not visible outside of this translation unit
//
template <>
struct Interface<Special>
{
void foo() { std::cout << "Special" << std::endl; }
};
3到使用,它的简单太:
// main.cpp
#include "interface.h"
class Special; // yes, it only costs a forward declaration
// which helps much in term of dependencies
int main(int argc, char* argv[])
{
Interface<Special> special;
foo(special);
return 0;
};
如果没有翻译单元为Special
定义Interface
的专用化符号,这是一个未定义的符号。
现在,我会认为这将需要export
关键字,据我所知,这在我的知识中从未在g ++中实现(并且只在C++编译器中实现过一次,其作者建议任何人不要在给定时间和精力的情况下它花了他们)。
我怀疑它有事情做与连接解决方法的模板...
- 你有没有见过这样的事之前?
- 它符合标准吗?或者您认为这是巧合吗?
我必须承认,我对构建挺纳闷......
因此,如果我理解正确的话,在“special.h”中包含“interface.h”并转发声明模板专用化'template <> struct Interface;'然后在“main.cpp” “special.h”,以便使程序格式良好,即使'Interface :: foo'方法的定义永远不会出现? –
2010-05-09 14:30:27
@Matthieu,正好!这就是你可以如何解决不幸的问题 – 2010-05-09 14:35:05
如果我正确地读了这个,这意味着任何程序(多个翻译单元),其中对于给定的一组参数存在模板的显式专门化,但是在一些其他翻译单元中,隐式专门化用于同一组参数是ODR违规,编译器不需要 - 也可能不能 - 发布诊断? 这是非常可怕的,也是另一个很好的理由,即在可能的情况下始终将主要模板部分专业化。 – Stewart 2010-05-09 18:24:27