【发布时间】:2011-06-06 05:43:31
【问题描述】:
我正在查看 Don Clugston 的 FastDelegate 迷你库,并注意到一个奇怪的语法技巧,其结构如下:
TemplateClass< void( int, int ) > Object;
看起来好像函数签名被用作模板实例声明的参数。
这种技术(其在 FastDelegate 中的出现显然是由于一个 Jody Hagins)被用来简化模板实例的声明,其中包含半任意数量的模板参数。
也就是说,它允许这样的事情:
// A template with one parameter
template<typename _T1>
struct Object1
{
_T1 m_member1;
};
// A template with two parameters
template<typename _T1, typename _T2>
struct Object2
{
_T1 m_member1;
_T2 m_member2;
};
// A forward declaration
template<typename _Signature>
struct Object;
// Some derived types using "function signature"-style template parameters
template<typename _Dummy, typename _T1>
struct Object<_Dummy(_T1)> : public Object1<_T1> {};
template<typename _Dummy, typename _T1, typename _T2>
struct Object<_Dummy(_T1, _T2)> : public Object2<_T1, _T2> {};
// A. "Vanilla" object declarations
Object1<int> IntObjectA;
Object2<int, char> IntCharObjectA;
// B. Nifty, but equivalent, object declarations
typedef void UnusedType;
Object< UnusedType(int) > IntObjectB;
Object< UnusedType(int, char) > IntCharObjectB;
// C. Even niftier, and still equivalent, object declarations
#define DeclareObject( ... ) Object< UnusedType( __VA_ARGS__ ) >
DeclareObject( int ) IntObjectC;
DeclareObject( int, char ) IntCharObjectC;
尽管有真正的骇人听闻的味道,但我发现这种对可变参数模板参数的恶搞模拟非常令人兴奋。
这个技巧的真正意义似乎在于我可以将诸如“Type1(Type2, Type3)”之类的文本结构作为参数传递给模板。所以这是我的问题:编译器究竟是如何解释这个结构的?它是函数签名吗?或者,它只是一个带有括号的文本模式?如果是前者,那么这是否意味着就模板处理器而言,任意函数签名都是有效类型?
一个后续问题是,既然上面的代码示例是有效代码,为什么 C++ 标准不允许您执行以下无法编译的操作?
template<typename _T1>
struct Object
{
_T1 m_member1;
};
// Note the class identifier is also "Object"
template<typename _T1, typename _T2>
struct Object
{
_T1 m_member1;
_T2 m_member2;
};
Object<int> IntObject;
Object<int, char> IntCharObject;
【问题讨论】:
-
+1,很好的问题,我是相关图书馆的忠实粉丝。
-
参见this article的“C++ 函数类型作为 DSL”段落
-
有关模拟可变参数模板参数的另一种方法,请参阅templog.svn.sourceforge.net/viewvc/templog/code/trunk/…