【问题标题】:C++ , Member function passed as template argumentC++,成员函数作为模板参数传递
【发布时间】:2015-04-02 11:12:41
【问题描述】:

我想传递函数eval2(T c, T &d),它是Algo1类中的成员函数

Algo1.h
#ifndef ALGO1_H
#define ALGO1_H

#include "Algo2.h"

template <typename T>
class Algo1
{
    private: T a, b;

    public:
    Algo1() : a(0), b(0) {}
    Algo1(T a_, T b_) : a(a_), b(b_) {}

    void anal(T &c);
    void eval1(T c);
    void eval2(T c, T &d);
    friend void get(Algo1 &al, T &a, T &b);
};
#endif

作为 anal(T &c) 函数中的模板参数。

Algo1.hpp
#ifndef ALGO1_HPP
#define ALGO1_HPP

template <typename T>
void Algo1<T>::anal(T &c) {
    Algo2<T>::process(eval2<T>, b, c);} //Pass the  member function, wrong

template <typename T>
void Algo1<T>::eval1(T c) {     a += c; }

template <typename T>
void Algo1<T>::eval2(T c, T &d) { d = a + b + c;}

#endif

在实践中,eval2() 表示一些处理成员数据的成本函数。包含方法 process() 的“目标”类看起来像

Algo2.h
#ifndef ALGO2_H
#define ALGO2_H

template <typename T>
class Algo2
{
    public:

    template <typename Function>
    static void process(Function f, T &x, T &res);
};
#endif

Algo2.hpp
#ifndef ALGO2_HPP
#define ALGO2_HPP

template <typename T>
template <typename Function>
void Algo2<T>::process(Function f, T &x, T &res)  { f(x, res); } //Call passed function as static

#endif

很遗憾,eval2(T c, T &d) 是处理成员数据的成员函数,不能声明为静态。但是,在类之外,它不能在没有对象的情况下被调用。因此,函数 process() 无法将传递的函数作为静态函数调用。为了解决问题并提取数据,声明并定义了友元函数 get(Algo1 &al, T &a, T &b )

template <typename T>
inline void get(Algo1 <T> &al, T &a, T &b )
{
    a = al.a;
    b = a1.b;
}

它被“内置”到非成员函数 eval3() 中

template <typename T>
inline void eval3(T c, T &d)
{
    Algo1 <T> alg;
    T a, b;
    get(alg, a, b);
}

函数 anal() 被改进为调用 eval3 而不是 eval 2 的形式

 template <typename T>
 void Algo1<T>::anal(T &c)
 {
    Algo2<T>::process(eval3<T>, b, c); //Pass the function OK
 }

我有两个问题:

  1. 有没有更舒适的方式来传递成员函数,同时保持调用为静态?

  2. 在哪里声明和定义 get() 和 eval3() 函数以避免错误

    错误 1 ​​错误 LNK2019:无法解析的外部符号“void __cdecl get(class Algo1 &,double &,double &)”(?get@@YAXAAV?$Algo1@N@@AAN1@Z) 在函数“void __cdecl eval3(double,double &)"

非常感谢您的帮助。

_____________评论________________

第二点已经解决了。而不是声明

 friend void get(Algo1 &al, T &a, T &b);

需要这样声明

 template <typename T>
 friend void get(Algo1 &al, T &a, T &b);

【问题讨论】:

  • 您可能想稍微调整一下函数的名称...

标签: c++ function templates arguments parameter-passing


【解决方案1】:
  1. 有没有更舒适的方法来传递成员函数,同时保持调用为静态?

使用 C++11 和 lambda,您可以这样做

template <typename T>
void Algo1<T>::anal(T &c) {
    Algo2<T>::process([=](T a1, T& a2) { return this->eval2(a1, a2); }, this->b, c);
}

在此之前,您必须手动创建仿函数,例如:

template<typename T>
class MyFunctor
{
public:
    explicit(Algo1<T>* algo1) : algo1(algo1) {}

    void operator () (T a1, T& a2) const
    {
        algo1->eval2(a1, a2);
    }
private:
    Algo1<T>* algo1;
};

然后:

template <typename T>
void Algo1<T>::anal(T &c) {
    Algo2<T>::process(MyFunctor<T>(this), this->b, c);
}

【讨论】:

  • 谢谢...我不熟悉新的 C++ 规范。函子是什么样子的,与“旧”规范有什么不同吗?
  • @Tomas:添加了 C++03 解决方案。
【解决方案2】:

您在类中作为友元函数(无模板)的get 函数原型与作为模板函数的定义原型不匹配。因此,未解析的外部链接器可能正在搜索朋友获取函数的定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 2013-11-06
    相关资源
    最近更新 更多