2009-11-27 86 views
1

我在努力找出为什么我无法使用模板类进行转换。如何在模板中使用std :: transform

这里是模板类的简化版本:

template<typename T> 
class base 
{ 
public : 
    base() : all_() {} 
    ~base() {} 
public: 
    bool add(T t) 
    { 
    typename vector<T>::iterator itr 
     = lower_bound(all_.begin(), all_.end(), t); 
    if (itr == all_.end() || *itr != t) 
     { 
     all_.push_back(t); 
     cout << "ok" << endl; 
     return true; 
     } 
    cout << "failed" << endl; 
    return false; 
    } 
    static bool addTo(base<T> *c, T t) 
    { 
    return c->add(t); 
    } 
private : 
    vector<T> all_; 
}; 

而这正是我试图利用变换来捕获所有从添加成员函数输出的布尔:

main() 
{ 
    base<int> test; 
    vector<bool> results; 
    vector<int> toAdd; 
    toAdd.push_back(10); 
    toAdd.push_back(11); 
    toAdd.push_back(10); 
    transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), 
      bind1st((bool(*)(base<int>*,int))base<int>::addTo, &test)); 
} 

的目标是使用base :: add或base :: addTo插入toAdd容器的每个成员,并捕获向量结果中的bool结果

+2

有什么问题吗?如果它是“为什么不编译这个代码”,那么C++中的函数定义必须具有返回类型,而'main'具有返回类型'int' ;-) – 2009-11-27 17:21:30

+0

你能解释一下你试图在转变? – Naveen 2009-11-27 17:23:21

+0

正确 - 无法编译它。主要完整类型不是我使用过的任何编译器的先决条件。 – youngthing 2009-11-27 17:23:54

回答

6

Try:

transform(toAdd.begin(), toAdd.end(), 
     back_inserter(results), 
     bind1st(mem_fun(&base<int>::add), &test)); 

问题不在于模板,而在于bind1st依靠额外的支持来工作(请参阅http://www.sgi.com/tech/stl/AdaptableBinaryFunction.html)。 AFAIK它不能在普通的旧函数指针上运行。

boost::bind可以做更多的事情,如果你想把它带入。对于这种情况你不需要它,但:mem_fun将一个非静态成员函数变成一个可适应的二进制函数。因此也不需要addTo,但是如果您确实需要在类似情况下使用静态成员函数,那么存在ptr_fun

+0

这是有效的。 感谢您的提示,特别是迂腐的提示。 – youngthing 2009-11-27 17:35:51

+0

而* reason的原理是'bind1st'不接受普通的函数指针。它需要仿函数对象。 'mem_fun'和'ptr_fun'函数将函数指针转换为适用于活页夹的函子。 – 2009-11-27 17:42:37

+0

@RobKennedy:谢谢,这很有意义,还有一些我还没有从Josutis STL书中找到。 我会给你和onebyone一个rec如果可以! – youngthing 2009-11-27 17:46:24

0

以下内容添加到您的基类:

typedef base<T>* first_argument_type; 
typedef T second_argument_type; 
typedef bool result_type; 

bool operator() (base<T> *c, T t) const { 
    return c->add(t); 
} 

和变化转变为:

transform(toAdd.begin(), toAdd.end(), 
      back_inserter(results), bind1st(base<int>(), &test)); 
+0

这将是好的,如果我的课(基地)只是要存储容器 - 我不介意提交operator()只是添加一个项目。虽然我的正确代码有更多的基地负责。 – youngthing 2009-11-27 17:40:15

+0

您不必在'base'类中添加添加,您可以创建一个小结构,比如说包含我提供的代码的'Adder'。然后用'Adder'代替基地。但mem_fun适配器也适用;) – 2009-11-27 17:42:14