【问题标题】:error in :c++ template function:c++ 模板函数中的错误
【发布时间】:2011-03-24 15:46:11
【问题描述】:

您好,我尝试在 vc++ 中构建一个模板函数,如下所示:

template<class _Fn0,class _Fn1>   void for_each(_Fn0 _Func0,_Fn1 _Func1)
{    
    _Func0(12);
    _Func1(12);

}

当我为 _Func0/1 使用一个全局函数时,这个工作正常。

void aglobal(int a)
{
    a++;
}
for_each(aglobal,aglobal);

但是当我使用 memeber 类函数时,我会收到错误消息。

class A
{
public:
    void aa(int a)
    {
        a++;
    }
    void bb(int b)
    {
        b++;
    }
    void cc()
    {
        for_each(&A::aa,&A::bb);
    }
};

错误 C2064:术语不计算为带 1 个参数的函数 1> 参见正在编译的函数模板实例化 'void for_each(_Fn0,_Fn1)' 的参考。

我该如何解决这个错误?

谢谢赫兹。

【问题讨论】:

  • 请注意,以下划线后跟大写字母的名称(如_Fn0_Func0)是保留的,因此您不能在代码中使用它们。编译器和标准库实现通常在内部使用这些名称。

标签: c++ class templates


【解决方案1】:

A::aaA::bb 是非静态成员函数;您试图将它们称为非成员函数。

只能在对象的实例上调用非静态成员函数。

要修复它,您可以

  1. aabb 设为静态,或者

  2. A 的实例传递给for_each,以便它可以调用该实例上的函数,或者

  3. 使用std::bind/std::tr1::bind/boost::bind将成员函数绑定到实例,然后再将其传递给函数模板,或者

  4. 编写一个函子,该函子存储指向您要在其上调用成员函数的A 实例的指针和指向您要调用的成员函数的指针;这实际上是bind 所做的(尽管bind 更为通用)。

【讨论】:

  • +1 请注意,以下划线大写开头的名称由实现保留。
  • @herzl:如果你想调用this上的两个成员函数:for_each(std::bind(&amp;A::aa, this, std::placeholders::_1), std::bind(&amp;A::bb, this, std::placeholders::_1))
  • @herzl:还要非常小心:std::for_each 是标准库函数的名称(在&lt;algorithm&gt; 中)。如果您向函数添加另一个参数,使其具有三个参数并且 using namespace std 或传递标准库类型的参数,您最终可能会调用错误的函数。
  • @James:是的,我将更改此函数的名称,这只是一个尝试名称。我部分理解您的示例我如何使用您的示例?在哪里定义 std::bind 我只看到 std::bind2nd 或 std::bind1st。我需要更多帮助才能使用您的示例。我怎样才能了解更多关于std::bind 谢谢
  • @herzl: bind 是 Boost 库的一个组件(在 &lt;boost/bind.hpp&gt; 中);它也包含在 C++ TR1 和 C++0x(&lt;functional&gt;)中。您的编译器可能还不支持其中任何一个,或者可能需要一些标志来启用它们。大多数最新的编译器都支持它们。您可以从the Boost documentation 了解有关bind 的所有信息。
【解决方案2】:

类的成员函数总是接受额外的参数“this”指针,所以你可以把它们设为静态来试试这个。

【讨论】:

    猜你喜欢
    • 2019-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多