Я смотрел на мини-библиотеку 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)" в качестве аргументов шаблонов. Итак, вот мои вопросы: как именно компилятор интерпретирует эту конструкцию? Является ли это сигнатурой функции? Или это просто текстовый шаблон с круглыми скобками? Если первое, то это означает, что любая произвольная сигнатура функции является допустимым типом в отношении процессора шаблонов?
Следующий вопрос будет заключаться в том, что, поскольку приведенный выше пример кода является допустимым кодом, почему стандарт С++ не позволяет вам делать что-то вроде следующего, которое не компилируется?
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;