Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)?
Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?
Может быть позволить компилятору самому вывести все необходимые типы?
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>();
А не расскажешь, что тебе надо на самом деле? А то в общем случае не заменишь, а в конкретном часто очень даже заменишь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Cavaler, Вы писали:
C>Добрый день!
C>Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)? C>Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?
C>Прямой подход типа C>
Здравствуйте, Cavaler, Вы писали:
C>Добрый день!
C>Интересно, есть ли теоретическая возможность одним параметром темплейта определить сразу два (и более типа)? C>Например, сделав параметром указатель на метод интерфейса, тем самым получить в темплейте как сам интерфейс, так и собственно указатель?
C>Прямой подход типа C>
C>что кажется слегка излишним, ибо вызов тогда выглядит как: C>
CallMe<MyInterface, &MyInterface::MyMethod>();
C>а хотелось бы просто C>
CallMe<&MyInterface::MyMethod>();
Тут где-то обман.
Как передается this ?
Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.
__>Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.
Здравствуйте, Аноним, Вы писали:
__>>Если передается только указатель на метод член класса, то как-то должен передаваться экземпляр класса для вызова метода. Вот оттуда можно и брать тип MyInterface.
А>Нельзя.
Здравствуйте, _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
--
Справедливость выше закона. А человечность выше справедливости.
Увы, ничего не выйдет. В объявлении основного шаблона callme сказано, T — это тип. И во всех специализациях этого шаблона его параметром может быть только тип. Конструкция же void (Interface::*method)(), примененая в специализации этого шаблона не является типом. А является константой — указателем на функцию член.
--
Справедливость выше закона. А человечность выше справедливости.