C++,作为模板参数传递的成员函数
C++ , Member function passed as template argument
我想传递函数eval2(T c, T &d),它是class 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() 表示一些处理成员数据的成本函数。 "destination" class 包含方法 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)是处理成员数据的成员函数,不能声明为static。但是,在 class 之外,没有对象就不能调用它。因此,函数 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;
}
是"built"进入了非成员函数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
}
我有两个问题:
有没有更舒适的方法来传递成员函数,同时保持静态调用?
在哪里声明和定义 get() 和 eval3() 函数以避免错误
Error 1 error LNK2019: 未解析的外部符号 "void __cdecl get(class Algo1 &,double &,double &)" (?get@@YAXAAV?$Algo1@N@@AAN1@Z) 在函数 "void __cdecl eval3(double,double &)"
[= 中引用50=]
非常感谢您的帮助。
_____________Comment________________
第二点已经解决。而不是声明
friend void get(Algo1 &al, T &a, T &b);
需要这样声明
template <typename T>
friend void get(Algo1 &al, T &a, T &b);
您在 class 作为友元函数(w/o 模板)中的 get
函数原型与作为模板函数的定义原型不匹配。因此,未解析的外部链接器可能正在搜索 friend get 函数的定义。
- Is there any more comfortable way how to pass a member function while keeping the call it as static?
使用 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);
}
我想传递函数eval2(T c, T &d),它是class 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() 表示一些处理成员数据的成本函数。 "destination" class 包含方法 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)是处理成员数据的成员函数,不能声明为static。但是,在 class 之外,没有对象就不能调用它。因此,函数 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;
}
是"built"进入了非成员函数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
}
我有两个问题:
有没有更舒适的方法来传递成员函数,同时保持静态调用?
在哪里声明和定义 get() 和 eval3() 函数以避免错误
Error 1 error LNK2019: 未解析的外部符号 "void __cdecl get(class Algo1 &,double &,double &)" (?get@@YAXAAV?$Algo1@N@@AAN1@Z) 在函数 "void __cdecl eval3(double,double &)"
[= 中引用50=]
非常感谢您的帮助。
_____________Comment________________
第二点已经解决。而不是声明
friend void get(Algo1 &al, T &a, T &b);
需要这样声明
template <typename T>
friend void get(Algo1 &al, T &a, T &b);
您在 class 作为友元函数(w/o 模板)中的 get
函数原型与作为模板函数的定义原型不匹配。因此,未解析的外部链接器可能正在搜索 friend get 函数的定义。
- Is there any more comfortable way how to pass a member function while keeping the call it as static?
使用 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);
}