Каков тип возврата boost:: bind?
Я хочу сохранить "связующее" функции в переменной, чтобы использовать ее повторно в следующем коде, используя свои функции перегрузки оператора. Вот код, который действительно делает то, что я хочу:
#include <boost/bind.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
class X
{
int n;
public:
X(int i):n(i){}
int GetN(){return n;}
};
int main()
{
using namespace std;
using namespace boost;
X arr[] = {X(13),X(-13),X(42),X(13),X(-42)};
vector<X> vec(arr,arr+sizeof(arr)/sizeof(X));
_bi::bind_t<int, _mfi::mf0<int, X>, _bi::list1<arg<1> > > bindGetN = bind(&X::GetN,_1);
cout << "With n =13 : "
<< count_if(vec.begin(),vec.end(),bindGetN == 13)
<< "\nWith |n|=13 : "
<< count_if(vec.begin(),vec.end(),bindGetN == 13 || bindGetN == -13)
<< "\nWith |n|=42 : "
<< count_if(vec.begin(),vec.end(),bindGetN == 42 || bindGetN == -42)
<< "\n";
return 0;
}
Меня беспокоит, конечно, строка:
bi::bind_t<int, _mfi::mf0<int, X>, _bi::list1<arg<1> > > bindGetN = bind(&X::GetN,_1);
Я получил тип, просто продумывая ошибку типа и анализируя сообщение об ошибке. Это, конечно, не очень хороший способ. Есть ли способ получить тип для "bindGetN"? Или, может быть, существуют разные способы создания аналогичных функций?
Изменить: я забыл упомянуть, что, так сказать, "стандартное" предложение использовать function
в этом случае не работает - потому что я хочу, чтобы моя операционная перегрузка.
Ответы
Ответ 1
Короткий ответ: вам не нужно знать (определенная реализация).
Это выражение привязки (std::tr1::is_bind_expression<T>::value
дает true для фактического типа).
Посмотрите
-
std::tr1::function<>
- BOOST_AUTO()
- С++ 0x 'auto' ключевые слова (Type Inference)
- закрыть cousing
decltype()
может помочь вам двигаться дальше
1.
std::tr1::function<int> f; // can be assigned from a function pointer, a bind_expression, a function object etc
int realfunc();
int realfunc2(int a);
f = &realfunc;
int dummy;
f = tr1::bind(&realfunc2, dummy);
2.
BOOST_AUTO() направлен на поддержку семантики С++ 0x auto без поддержки компилятора С++ 0x:
BOOST_AUTO(f,boost::bind(&T::some_complicated_method, _3, _2, "woah", _2));
3.
По существу то же самое, но с поддержкой компилятора:
template <class T> struct DoWork { /* ... */ };
auto f = boost::bind(&T::some_complicated_method, _3, _2, "woah", _2));
DoWork<decltype(T)> work_on_it(f); // of course, using a factory would be _fine_
Обратите внимание, что авто, вероятно, был изобретен для такого рода ситуаций: фактический тип - это "вы не хотите знать" и может различаться в разных компиляторах/платформах/библиотеках