我想知道是否以及如何在类成员函数中定义一个函数对象,以便直接使用它,例如std :: transform函数。
我知道这个例子有点愚蠢,只是为了表明我遇到的问题。
文件“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>&)’
所以我认为在std :: transform中使用struct“functor”时会出现问题。有人能告诉我问题是什么吗?
使用:
Ubuntu Linux下的gcc-4.2编译器。
提前致谢,
勒。
答案 0 :(得分:4)
正如Alexandre已经指出的那样,你不能使用具有函数作用域的类型(或根本没有名称)作为模板参数。但是,您可以使用本地类型的静态成员函数作为函子参数:
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));
}
答案 1 :(得分:2)
可悲的是,这不起作用。标准不允许将本地类用作模板参数,因此该方法失败(请某人引用标准的相关部分):
14.3.1 / 2:“本地类型,没有链接的类型,未命名的类型或类型 从任何这些类型复合而成 不得用作 模板的模板参数 型参数“。
如果您可以访问C ++ 0x编译器,则可以使用。
本地课程可能很强大,但它们的使用仅限于“类型擦除成语”:
struct abstract_foo { ... };
template <typename T>
abstract_foo* make_concrete_foo(...)
{
struct foo : abstract_foo
{
// Depends on T
};
return new foo(...);
}