Re[3]: Инстанциирование в шаблонном параметре
От: MaximE Великобритания  
Дата: 27.12.04 07:46
Оценка: 4 (2)
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 Yegorushkin
Posted via RSDN NNTP Server 1.9 delta
Инстанциирование в шаблонном параметре
От: Undead  
Дата: 26.12.04 14:24
Оценка:
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>'
Как правильно записать то, что имелось ввиду?
Re: Инстанциирование в шаблонном параметре
От: MaximE Великобритания  
Дата: 26.12.04 19:42
Оценка:
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 Yegorushkin
Posted via RSDN NNTP Server 1.9 delta
Re[2]: Инстанциирование в шаблонном параметре
От: Undead  
Дата: 26.12.04 20:10
Оценка:
Здравствуйте, 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 );
Re[4]: Инстанциирование в шаблонном параметре
От: Undead  
Дата: 27.12.04 15:35
Оценка:
Данный фикс не подходит, но я все понял.
"Курица и яйцо", прикольно
Спасибо.
Re: Инстанциирование в шаблонном параметре
От: ReV01VeR  
Дата: 28.12.04 04:41
Оценка:
Здравствуйте, 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.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.