Два типа в одном параметре темплейта
От: Cavaler  
Дата: 23.12.08 12:00
Оценка:
Добрый день!

Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)?
Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?

Прямой подход типа
template <void (Interface::method)()> void CallMe() { ...}

не срабатывает, говорит что не знаю шо за Interface, приходится писать
template <class Interface, void (Interface::method)()> void CallMe() { ...}

что кажется слегка излишним, ибо вызов тогда выглядит как:
CallMe<MyInterface, &MyInterface::MyMethod>();

а хотелось бы просто
CallMe<&MyInterface::MyMethod>();
Re: Два типа в одном параметре темплейта
От: Bell Россия  
Дата: 23.12.08 12:16
Оценка: 4 (1)
Здравствуйте, Cavaler, Вы писали:

Может быть позволить компилятору самому вывести все необходимые типы?
template<class R, class T>
R CallMe(R (T::*mem_fn)()) { T t; return (t.*mem_fn)(); }

struct test
{
   int fn() { return 1; }
};

int main()
{
   int i = CallMe(&test::fn);
   return 0;
}
Любите книгу — источник знаний (с) М.Горький
Re[2]: Два типа в одном параметре темплейта
От: Аноним  
Дата: 23.12.08 17:18
Оценка:
B>template<class R, class T>
B>R CallMe(R (T::*mem_fn)()) { T t; return (t.*mem_fn)(); }

Это другая конструкция с точки зрения типов — здесь такая же разница как между следующими двумя функциями:

template <int parameter>
void Function ()
{
}

void Function (int parameter)
{
}


Чувствуете разницу?

Но, похоже, C++ не умеет «в одном параметре передавать два типа».

Так что, уродскую конструкцию

CallMe<MyInterface, &MyInterface::MyMethod>();


не заменишь на

CallMe<&MyInterface::MyMethod>();
Re[3]: Два типа в одном параметре темплейта
От: Alexander G Украина  
Дата: 23.12.08 17:24
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Так что, уродскую конструкцию


А>
CallMe<MyInterface, &MyInterface::MyMethod>();


А>не заменишь на


А>
CallMe<&MyInterface::MyMethod>();


Можно через #define завернуть в унарный макрос.
Русский военный корабль идёт ко дну!
Re[3]: Два типа в одном параметре темплейта
От: Erop Россия  
Дата: 23.12.08 18:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Так что, уродскую конструкцию

А>
CallMe<MyInterface, &MyInterface::MyMethod>();


А>не заменишь на

А>
CallMe<&MyInterface::MyMethod>();


А не расскажешь, что тебе надо на самом деле? А то в общем случае не заменишь, а в конкретном часто очень даже заменишь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Два типа в одном параметре темплейта
От: vopl Россия  
Дата: 24.12.08 11:34
Оценка:
Здравствуйте, Cavaler, Вы писали:

C>Добрый день!


C>Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)?

C>Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?

C>Прямой подход типа

C>
template <void (Interface::method)()> void CallMe() { ...}


Здесь method — не тип.

C>не срабатывает, говорит что не знаю шо за Interface, приходится писать

C>
template <class Interface, void (Interface::method)()> void CallMe() { ...}


Здесь Interface — тип, method — не тип.

C>что кажется слегка излишним, ибо вызов тогда выглядит как:

C>
CallMe<MyInterface, &MyInterface::MyMethod>();

C>а хотелось бы просто
C>
CallMe<&MyInterface::MyMethod>();
Re: Два типа в одном параметре темплейта
От: _nn_  
Дата: 05.01.09 20:51
Оценка:
Здравствуйте, Cavaler, Вы писали:

C>Добрый день!


C>Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)?

C>Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?

C>Прямой подход типа

C>
template <void (Interface::method)()> void CallMe() { ...}

C>не срабатывает, говорит что не знаю шо за Interface, приходится писать
C>
template <class Interface, void (Interface::method)()> void CallMe() { ...}

C>что кажется слегка излишним, ибо вызов тогда выглядит как:
C>
CallMe<MyInterface, &MyInterface::MyMethod>();

C>а хотелось бы просто
C>
CallMe<&MyInterface::MyMethod>();


Тут где-то обман.
Как передается this ?
Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Два типа в одном параметре темплейта
От: Аноним  
Дата: 06.01.09 15:12
Оценка:
__>Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.

Нельзя.
Re[3]: Два типа в одном параметре темплейта
От: _nn_  
Дата: 06.01.09 19:09
Оценка:
Здравствуйте, Аноним, Вы писали:

__>>Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.


А>Нельзя.


Что значит нельзя ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Два типа в одном параметре темплейта
От: mgopshtein  
Дата: 06.01.09 23:10
Оценка:
Здравствуйте, Cavaler, Вы писали:

C>Прямой подход типа

C>
template <void (Interface::method)()> void CallMe() { ...}

C>не срабатывает, говорит что не знаю шо за Interface, приходится писать

А если как-то так:

template <typename T> struct callme;

template<class Interface, void (Interface::method)()>
struct callme<void (Interface::method)()> {
   void operator()() {
      Interface i;
      (i::*method)();
   }
};


И тогда можно использовать
callme<&A::doPrint>


Только, насколько я помню, с template function такое не работает, только у классов есть partial specialization.
Re[2]: Два типа в одном параметре темплейта
От: rg45 СССР  
Дата: 06.01.09 23:34
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Как передается this ?

__>Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.

Тут могут быть разные варианты. Например, this может быть сформирован заранее, или экземпляр класса может создаваться внутри вызова CallMe. Проблема не в этом. Допустим, ссылка на экземпляр класса передается как параметр функции CallMe, это не дает нам ровным счетом ничего. А все дело в том, что в данном случае компилятор не даст нам поменять местами параметры шаблона в расчете на то, что второй параметр шаблона (имя класса) будет выведен по параметру, переданному в функцию при вызове. В самом деле, для того, чтобы вызов функции CallMe выглядел так:
CallMe<&MyInterface::MyMethod>(my_instance);
необходимо, чтобы ее определение было таким:
template <void (Interface::*method)(), typename Interface> void CallMe(Interface&); //error: name followed by "::" must be a class or namespace name
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: Два типа в одном параметре темплейта
От: rg45 СССР  
Дата: 06.01.09 23:48
Оценка:
Здравствуйте, mgopshtein, Вы писали:

M>А если как-то так:


M>
M>template <typename T> struct callme;

M>template<class Interface, void (Interface::method)()>
M>struct callme<void (Interface::*method)()> {
M>   void operator()() {
M>      Interface i;
M>      (i::*method)();
M>   }
M>};
M>


M>И тогда можно использовать

M>
M>callme<&A::doPrint>
M>


Увы, ничего не выйдет. В объявлении основного шаблона callme сказано, T — это тип. И во всех специализациях этого шаблона его параметром может быть только тип. Конструкция же void (Interface::*method)(), примененая в специализации этого шаблона не является типом. А является константой — указателем на функцию член.
--
Справедливость выше закона. А человечность выше справедливости.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.