template <typename T>
struct Formatter
{
};
template <typename T>
struct MemberFunction
{
typedef void(T::*Type)(void);
};
template <typename T>
struct Formatter<typename MemberFunction<T>::Type >
{
/*...*/
};
int main()
{
}
VC 7.1 не компилит:
error C2764: 'T' : template parameter not used in partial specialization 'Formatter<MemberFunction<T>::Type>'
Как правильно записать то, что имелось ввиду?
Undead wrote:
> > template <typename T>
> struct Formatter
> {
> };
>
> template <typename T>
> struct MemberFunction
> {
> typedef void(T::*Type)(void);
> };
>
> template <typename T>
> struct Formatter<typename MemberFunction<T>::Type >
> {
> /*...*/
> };
>
> int main()
> {
> }
>
>
> VC 7.1 не компилит:
> error C2764: 'T' : template parameter not used in partial specialization 'Formatter<MemberFunction<T>::Type>'
> Как правильно записать то, что имелось ввиду?
А что именно имелось ввиду?
Может так:
template <typename T>
struct Formatter
{
typedef typename MemberFunction<T>::Type Type;
/*...*/
};
?
--
Maxim YegorushkinPosted via RSDN NNTP Server 1.9 delta
Здравствуйте, MaximE, Вы писали:
ME>А что именно имелось ввиду?
ME>Может так:
ME>ME>template <typename T>
ME>struct Formatter
ME>{
ME> typedef typename MemberFunction<T>::Type Type;
ME>/*...*/
ME>};
ME>
Нет, я хотел специализировать Formatter для функций-членов определенного вида.
class Server
{
public:
void Run();
};
// ...
Formatter< MemberFunction<Server>::Type > formatter;
formatter.Serialize( &Server::Run );
Undead wrote:
[]
> Нет, я хотел специализировать Formatter для функций-членов определенного вида.
>
> template <typename T>
> struct Formatter
> {
> };
>
> template <typename T>
> struct MemberFunction
> {
> typedef void(T::*Type)(void);
> };
>
> template <typename T>
> struct Formatter<typename MemberFunction<T>::Type >
> {
> /*...*/
> };
>
> int main()
> {
> }
> > class Server
> {
> public:
> void Run();
> };
> // ...
> Formatter< MemberFunction<Server>::Type > formatter;
> formatter.Serialize( &Server::Run );
>
Этот код компилируется на gcc и comeau online. Но твоя специализация никогда не будет выбрана, так как компилятор не может вывести T из void(T::*Type)(void), когда последний у тебя записан как typename MemberFunction<T>::Type. Проблема курицы и яйца: чтобы получить MemberFunction<T>::Type нужно знать T, чтобы получить T нужно знать MemberFunction<T>::Type.
Пофиксить можно так:
template <typename T>
struct MemberFunction
{
typedef void(T::*Type)(void);
};
template <typename T, class U = typename MemberFunction<T>::Type>
struct Formatter
{
};
template <typename T>
struct Formatter<T, typename MemberFunction<T>::Type>
{
};
class Server
{
public:
void Run();
};
// ...
Formatter<Server, MemberFunction<Server>::Type> formatter_0;
Formatter<Server> formatter_1; // то же, что и formatter_0
--
Maxim YegorushkinPosted via RSDN NNTP Server 1.9 delta
Данный фикс не подходит, но я все понял.
"Курица и яйцо", прикольно

Спасибо.
Здравствуйте, Undead, Вы писали:
U>U>template <typename T>
U>struct Formatter
U>{
U>};
U>template <typename T>
U>struct MemberFunction
U>{
U> typedef void(T::*Type)(void);
U>};
U>template <typename T>
U>struct Formatter<typename MemberFunction<T>::Type >
U>{
U>/*...*/
U>};
U>int main()
U>{
U>}
U>
U>VC 7.1 не компилит:
U>error C2764: 'T' : template parameter not used in partial specialization 'Formatter<MemberFunction<T>::Type>'
U>Как правильно записать то, что имелось ввиду?
Если не использовать обертки вроде MemberFunction, то по-моему так:
template <typename T>
struct Formatter
{
};
template <class T, typename R, typename A>
struct Formatter<R (T::*)(A)>
{
};
Но мой компилятор(BCB6) на такое ругается, хотя такое:
template <typename R, typename A>
struct Formatter<R (*)(A)>
{
};
воспринимает OK.
Когда я столкнулся с этой проблемой, я как раз и использовал обертку типа MemberFunction:
template <class T, typename R, typename A>
struct MemberFunction
{
typedef R (T::*Type)(A);
};
На специализацию Formatter'а типом MemberFunction<T,R,A>::Type BCB6 тоже ругается,
поэтому я специализировал его типом обертки,
а уже внутри можно обращаться к MemberFunction<T, R, A>::Type:
template <class T, typename R, typename A>
struct Formatter< MemberFunction<T, R, A> >
{
static void f() { std::cout << typeid(MemberFunction<T, R, A>::Type).name(); }
};
struct Foo;
int main(int argc, char* argv[])
{
Formatter< MemberFunction<Foo, int, double> >::f();
std::cin.get();
return 0;
}
Вроде, работало OK.