Интересно, если и как возможно определить функциональный объект в функции членства классов для использования его непосредственно с, например, станд.:: преобразуйте функцию.
Я знаю, что пример немного глуп, он должен только показать проблему, с которой мне противостоят.
Файл "example.h"
class Example {
public:
//.. constructor and destructor stuff
std::string toString() const; //Converts 'mVal' to a std::string
private:
std::vector<int> mVal; //Only one digit numbers are allowed ([0-9])
}
Файл "example.cpp"
std::string Example::toString() const
{
//The functor which should be used in std::transform
struct {
char operator()(const int number) {
char c;
//"Convert" 'number' to a char
return c;
};
} functor;
//Transform the integers to char
std::string str(mVal.size(), '0'); //Allocate enough space
std::transform(mVal.begin(), mVal.end(), str.begin(), functor);
return str;
};//toString()
С тех пор, как я пытался реализовать функциональный объект непосредственно в функции членства как в "example.cpp", код не становится скомпилированным. Сообщение об ошибке, которое я получаю:
error: no matching function for call to ‘transform(__gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, Example::toString() const::<anonymous struct>&)’
Таким образом, я думаю, что проблема подходит при использовании структуры "функтор" в станд.:: преобразовать. Кто-то может сказать мне, какова проблема?
Используя:
компилятор gcc-4.2 в соответствии с Ubuntu Linux.
Заранее спасибо,
René.
Как уже указывал Александр, вы не можете использовать тип с областью действия функции (или вообще без имени) в качестве параметра шаблона. Однако вы можете использовать статическую функцию-член локального типа в качестве параметра функтора:
int main()
{
struct F {
static int fn(int x)
{
return x+x;
}
};
int v[5]={1,2,3,4,5};
std::transform(v+0,v+5,v+0,F::fn);
}
Если вам нужно локальное состояние в вашей функции и вы не хотите прибегать к идиоме стирания типа, вы можете обмануть с приведением локальный тип прочь:
int main()
{
struct F {
int k;
int call (int n) const
{
return n+k;
}
static int fn(void *p, int x)
{
return ((F*)p)->call(x);
}
};
int v[5]={1,2,3,4,5};
F f;
f.k=123;
std::transform(v+0,v+5,v+0,std::bind1st(std::ptr_fun(F::fn),(void*)&f));
}
К сожалению, это не сработает. Стандарт запрещает использовать локальные классы в качестве аргументов шаблона, поэтому подход не работает (пожалуйста, кто-нибудь, процитируйте соответствующую часть Стандарта):
14.3.1/2: "Локальный тип, тип без связи, неименованный тип или тип составленный из любого из этих типов не должен использоваться в качестве шаблон-аргумент для шаблона type-parameter."
Если у вас есть доступ к компилятору C++0x, то это работает.
Локальные классы могли бы быть мощными, но их использование несколько ограничено "идиомой стирания типов":
struct abstract_foo { ... };
template <typename T>
abstract_foo* make_concrete_foo(...)
{
struct foo : abstract_foo
{
// Depends on T
};
return new foo(...);
}