【问题标题】:std::bind with template member functionstd::bind 与模板成员函数
【发布时间】:2014-01-09 05:38:44
【问题描述】:

我有一个奇怪的问题,我无法绑定这个模板成员函数, 所有这些代码都编译:http://ideone.com/wl5hS8

这是一个简单的代码:我有一个ExecutionList,它应该在std::vector 中保存可调用函数。我现在可以通过调用ExecutionList::addFunctor 添加功能。但是在那里,我无法绑定到template<typename T> void Functor::calculate(T * t)。我在问我为什么,这里缺少什么,编译器无法以某种方式推断出我写的内容

m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) );

*错误:*

error: expected primary-expression before ‘>’ token
                 m_calculationList.push_back( std::bind(T::calculate<Type>, extForce, std::placeholders::_1 ) );
                                                                     ^

守则:

#include <functional>
#include <iostream>
#include <vector>

struct MyType{
    static int a;
    int m_a;
    MyType(){a++; m_a = a;}

    void print(){
        std::cout << "MyType: " << a << std::endl;
    }
};
int MyType::a=0;


struct Functor{

    static int a;
    int m_a;

    Functor(){a++; m_a = a;}

    // Binding this function does not work 
    template<typename T>
    void calculate(T * t){}

    // Binding this function works!!!
    void calculate2(MyType * t){
        std::cout << " Functor: " << m_a <<std::endl;
        t->print();
    }

};

int Functor::a=0;

// Binding this function works!!!
template<typename T>
void foo( T * t){}

class ExecutionList{
    public:
        typedef MyType Type;

        template<typename T>
        void addFunctor(T * extForce){
            //m_calculationList.push_back( std::bind(&T::calculate<Type>, extForce, std::placeholders::_1 ) );   /// THIS DOES NOT WORK
            m_calculationList.push_back( std::bind(&T::calculate2, extForce, std::placeholders::_1 ) );
            m_calculationList.push_back( std::bind(&foo<Type>, std::placeholders::_1 ) );
        }


        void calculate(Type * t){
            for(auto it = m_calculationList.begin(); it != m_calculationList.end();it++){
                (*it)(t); // Apply calculation function!
            }
        }

    private:
        std::vector< std::function<void (Type *)> > m_calculationList;
};



int main(){
    MyType b;
    ExecutionList list;
    list.addFunctor(new Functor());
    list.addFunctor(new Functor());
    list.calculate(&b);
}

【问题讨论】:

  • 所以这意味着我需要一些typename 字?这有意义吗,因为它不是类型而是函数指针
  • 还有另一个歧义词:templatestd::bind(&amp;T::template calculate&lt;Type&gt;, ...) 应该可以工作。此外,总是包含您收到的错误消息。 “不工作”没有帮助。
  • 啊,该死的,我认为它是这些愚蠢的事情之一,但从未在类型前面使用模板,只有在 a.template foo&lt;Type&gt; 的情况下,如果 foo 不可推断

标签: templates c++11 std-function stdbind function-binding


【解决方案1】:

您似乎缺少模板关键字。如果 T 是一个模板参数并且 T::calculate 引用一个模板,你需要告诉编译器计算是一个模板,而不是你尝试使用小于运算符与其他东西进行比较的静态变量:

T::template calculate<Type>

几年前我遇到了完全相同的问题,但今天(C++11 后)我可能会使用更简单的 lambda 来解决它:

std::function<void(Type*)> func = [obj](Type*param){obj.calculate(param);};

无论如何,尽量减少new 的使用次数。寻找更好的方法来管理您的资源。您的代码似乎泄漏了几个仿函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-15
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2016-10-04
    • 2021-04-27
    相关资源
    最近更新 更多