Я пытался создать помощник шаблона для указателей на функции-члены, основная идея в том, чтобы иметь возможность делать такие вещи:
template <typename T, typename R> struct TStruct
{
typedef T value_type;
typedef R return_type;
R Function(T &);
};
struct Struct
{
int Function(const int &);
};
typedef TStruct<const int &, int> A;
FunctionPointer<A, A::return_type, A::value_type>::pointer p = &A::Function;
typedef FunctionPointer<Struct, int, const int &>::pointer FPointer;
Делая это, я понял, что объявление указателя без помощника короче (это уже не вопрос;), но это привело меня к ошибке, которую я не понимаю. Предположим, у нас есть две версии помощника:
template <typename Type, typename Return, typename Parameter> struct Good
{
typedef Return (Type::*pointer)(Parameter);
};
template <typename Type, typename Return, typename Parameter, Return (Type::*Pointer)(Parameter)> struct Bad
{
typedef Parameter pointer;
};
Good
каждый определяет указатель на тип функции-члена в теле структуры, а Bad
один определяет его в параметрах шаблона, а затем typedef
это в структуре тела.
С использованием Good
структурируйте мою тестовую программу:
int main(int argc, char **argv)
{
// No compilation errors
Good<A, A::return_type, A::value_type>::pointer GoodTStructPtr = &A::Function;
Good<Struct, int, const int &>::pointer GoodStructPtr = &Struct::Function;
return 0;
}
Но если Bad
используется структура, есть ошибка компиляции:
int main(int argc, char **argv)
{
// invalid initialization of reference of type ‘const int&’
// from expression of type ‘int (TStruct<const int&, int>::*)(const int&)’
Bad<A, A::return_type, A::value_type, &A::Function>::pointer BadTStructPtr = &A::Function;
// invalid initialization of reference of type ‘const int&’
// from expression of type ‘int (Struct::*)(const int&)’
Bad<Struct, int, const int &, &Struct::Function>::pointer BadStructPtr = &Struct::Function;
return 0;
}
НАСКОЛЬКО МНЕ ИЗВЕСТНО, Good::pointer
а также Bad::pointer
оба типа Return (Type::*)(Parameter)
поэтому они должны быть в состоянии указать на &A::Function
или же Struct::Function
, но я явно ошибаюсь, но я не знаю почему. Это кажется что существует другое поведение, когда тип объявляется в теле шаблонного объекта и когда он объявляется как параметр шаблона.
Итак, вопрос: Почему не работает Bad::pointer
как указатель на функцию &A::Function
или же &Struct::Function
?
Ты имел ввиду?
template <typename Type,
typename Return,
typename Parameter,
Return (Type::*Pointer)(Parameter)> struct Bad
{
typedef Pointer pointer;
// ^^^^^^^ (not Parameter)
};
Других решений пока нет …