Я новичок в C++, и сейчас я играю с шаблонами, чтобы лучше понять их. Вот что я пробовал:Передача функтора или функции в качестве аргумента
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
T val1;
T val2;
public:
someContainer(const T& in1, const T& in2)
:val1(in1), val2(in2) {}
template <template <typename Ty> class Comp>
void sort()
{
bool result = Comp<T>()(val1, val2);
cout << result << endl;
return;
}
};
template <typename R>
class Compare
{
public:
bool operator() (const R& a, const R& b)
{
return a>b;
}
};
int main()
{
someContainer<int> myCont(7,6);
myCont.sort<Compare>();
cin.ignore();
return 0;
}
Я хочу сделать почти то же самое, но для функции на этот раз. В основном что-то вроде:
myCont.sort<function>();
Просто чтобы быть уверенным, - я не хочу, чтобы это:
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
T val1;
T val2;
public:
someContainer(const T& in1, const T& in2)
:val1(in1), val2(in2) {}
template <class Func>
void sort(Func func)
{
bool result = func(val1,val2);
cout << result << endl;
return;
}
};
//Try for sort functor
template <typename R>
bool compare(const R& a, const R& b)
{
return a>b;
}
int main()
{
someContainer<int> myCont(7,6);
myCont.sort(compare<int>);
cin.ignore();
return 0;
}
/Edit: Я понимаю, что, возможно, не было точно ясно. Я хочу иметь возможность позвонить myCont.sort<function>
это возможно? Я понимаю, что функция не то, что вы назвали бы класс однако можно передать обобщенную функцию для сортировки():
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
T val1;
T val2;
public:
someContainer(const T& in1, const T& in2)
:val1(in1), val2(in2) {}
template <typename Ty>
void sort(bool (*_comp)(const Ty&, const Ty&))
{
cout << "Comp is of type: " << typeid(_comp).name() << endl;
cout << _comp(val1, val2) << endl;
return;
}
};
template <typename R>
bool compare(const R& a, const R& b)
{
return a>b;
}
int main()
{
someContainer<int> myCont(7,6);
myCont.sort(compare<int>);
cin.ignore();
return 0;
}
Я даже могу настроить свой тип возвращаемого значения:
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
T val1;
T val2;
public:
someContainer(const T& in1, const T& in2)
:val1(in1), val2(in2) {}
template <typename Ret, typename Ty>
void sort(Ret (*_comp)(const Ty&, const Ty&))
{
cout << "Comp is of type: " << typeid(_comp).name() << endl;
cout << _comp(val1, val2) << endl;
return;
}
};
template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
return a>b;
}
int main()
{
someContainer<int> myCont(7,6);
myCont.sort(compare<bool,int>);
cin.ignore();
return 0;
}
Но это не проблема. Я знаю, что я не объясняю это как можно лучше, поэтому, если вы хотите, чтобы я что-то добавил, скажите мне, что. Моя идея в том, что я хочу иметь возможность сделать что-то вроде: myCont.sort(); или myCont.sort (функция);
Суть вопроса: Есть ли способ передать шаблон функции в качестве аргумента шаблона другой функции - так же, как я прошел шаблон класса в качестве аргумента шаблона другой функции:
myCont.sort<Compare>(); // Compare is a template - not a template specialization
//later in sort we got Comp<T>()()
Если я получил шаблон функции называется сравнить есть способ сделать любое из следующих действий:
myCont.sort<compare>();
myCont.sort(compare);
Я хочу передать шаблон функции - не конкретизацией сравнить - Я могу сделать это с помощью функтора, поэтому я задаюсь вопросом, могу ли я сделать это с помощью функции. Я не хочу иметь:
myCont.sort(compare<some_type>);
Я хочу взять шаблон функции, а затем получить специализацию для него внутри рода().
Заранее благодарен!
P.S .: Кажется, комментарии могут быть только небольшого размера, так вот еще один вопрос: Как вы думаете, что это (myCont.sort(compare)
) было бы возможно (если бы значение по умолчанию для параметров шаблона функции в C++) с этим кодом?
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
T val1;
T val2;
public:
someContainer(const T& in1, const T& in2)
:val1(in1), val2(in2) {}
template <typename Ret = bool ,typename Ty = T>
void sort(Ret (*_comp)(const T&, const T&))
{
cout << "Comp is of type: " << typeid(_comp).name() << endl;
cout << _comp(val1, val2) << endl;
return;
}
};
template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
return a>b;
}
int main()
{
someContainer<int> myCont(7,6);
myCont.sort(compare);
cin.ignore();
return 0;
}
P.S.
Btw все началось со мной, интересно, почему я не могу скомпилировать это (очевидно, из-за отсутствия someFunc, но это логично, что список.сортировать должны быть в состоянии вывести тип SomeFunc от типа, для которого этот список является специализированным):
#include <iostream>
#include <list>
using namespace std;
template <typename T>
void display(const T& input)
{
for(auto i = input.cbegin(); i!=input.cend(); ++i)
cout << *i << ' ';
cout << endl;
return;
}
template <typename R>
bool someFunc(const R& in1, const R& in2)
{
return in1>in2;
}
int main()
{
list<int> myList;
myList.push_back(5);
myList.push_back(137);
myList.push_back(-77);
display(myList);
myList.sort(someFunc); //change it to myList.sort(someFunc<int>) and it works
//however I believe the compiler should be able to infer the type of someFunc from
//the type of myList - I guess the STL just wasn't written for having template
//functions as a binary predicate
display(myList);
cin.ignore();
return 0;
};
Итак, в чем ваш вопрос? –
К сожалению, 14.3.3/1: «A _template-argument_ для шаблона _template-parameter_ должен быть именем шаблона класса или шаблона псевдонима, выраженным как _id-expression_». Таким образом, шаблон функции не может быть аргументом шаблона, например шаблоном класса. – aschepler