gpt4 book ai didi

c++ - 由 traits [policies, actually] 实例化的类成员函数

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:39:10 27 4
gpt4 key购买 nike

我不愿意说我想不通,但我想不通。我用谷歌搜索并搜索了 Stack Overflow,但一无所获。

这个问题的抽象形式可能过于模糊,我如何使用 traits-pattern 来实例化成员函数? [更新:我在这里使用了错误的术语。应该是“政策”而不是“特质”。特征描述现有的类。策略规定合成类。] 在对我 10 多年前编写的一组多元函数优化器进行现代化改造时出现了这个问题。

所有优化器都通过选择远离当前最佳点(“更新”)的参数空间的直线路径进行操作,然后在该线上找到更好的点(“线搜索”),然后测试“完成”条件,如果没有完成,则进行迭代。

有不同的方法来进行更新、行搜索、完成测试和其他事情。连连看。不同的更新公式需要不同的状态变量数据。例如,LMQN更新需要一个 vector ,BFGS更新需要一个矩阵。如果评估梯度很便宜,线搜索应该这样做。如果不是,它应该只使用函数评估。有些方法比其他方法需要更准确的线搜索。这些只是一些例子。

原始版本通过虚函数实例化了几个组合。通过设置在运行时测试的模式位来选择某些特征。呸。用#define 定义特征,用#ifdef 和宏定义成员函数是微不足道的。但那是二十年前的事了。这让我很烦恼,我想不出一个现代的方式。

如果只有一个特征不同,我可以使用奇怪的重复模板模式。但我看不出有什么办法可以将其扩展到特征的任意组合。

我尝试使用 boost::enable_if 等来实现。专门的状态信息很容易。我设法完成了函数,但只能求助于以 this 指针作为参数的非友元外部函数。我什至从来没有想过如何让函数成为 friend ,更不用说成员函数了。编译器 (VC++ 2008) 总是提示事情不匹配。我会大喊,“SFINAE,你这个白痴!”但白痴可能是我。

也许 tag-dispatch 是关键。我还没有深入了解这一点。

这当然是可能的,对吧?如果是这样,最佳做法是什么?

更新:这是另一种尝试解释它的方法。我希望用户能够为自定义优化器填写订单( list ),例如从中文菜单中订购 - 一个来自 A 列,一个来自 B 列,等等。服务员,来自 A 列(更新程序) ,我将使用 Cholesky-decompositon 酱更新 BFGS。请从 B 列(线搜索器)中使用 eta 为 0.4 和 rho 为 1e-4 的三次插值线搜索。等等……

更新:好的,好的。这是我做过的游戏。我不情愿地提供它,因为我怀疑这是一种完全错误的方法。它在 vc++ 2008 下运行良好。

#include <boost/utility.hpp>
#include <boost/type_traits/integral_constant.hpp>

namespace dj {

struct CBFGS {
void bar() {printf("CBFGS::bar %d\n", data);}
CBFGS(): data(1234){}
int data;
};

template<class T>
struct is_CBFGS: boost::false_type{};

template<>
struct is_CBFGS<CBFGS>: boost::true_type{};

struct LMQN {LMQN(): data(54.321){}
void bar() {printf("LMQN::bar %lf\n", data);}
double data;
};

template<class T>
struct is_LMQN: boost::false_type{};

template<>
struct is_LMQN<LMQN> : boost::true_type{};

// "Order form"
struct default_optimizer_traits {
typedef CBFGS update_type; // Selection from column A - updaters
};

template<class traits> class Optimizer;

template<class traits>
void foo(typename boost::enable_if<is_LMQN<typename traits::update_type>,
Optimizer<traits> >::type& self)
{
printf(" LMQN %lf\n", self.data);
}

template<class traits>
void foo(typename boost::enable_if<is_CBFGS<typename traits::update_type>,
Optimizer<traits> >::type& self)
{
printf("CBFGS %d\n", self.data);
}

template<class traits = default_optimizer_traits>
class Optimizer{
friend typename traits::update_type;
//friend void dj::foo<traits>(typename Optimizer<traits> & self); // How?
public:
//void foo(void); // How???
void foo() {
dj::foo<traits>(*this);
}
void bar() {
data.bar();
}
//protected: // How?
typedef typename traits::update_type update_type;
update_type data;
};

} // namespace dj



int main() {
dj::Optimizer<> opt;
opt.foo();
opt.bar();
std::getchar();
return 0;
}

最佳答案

一个简单的解决方案可能是只使用基于标签的转发,例如像这样:

template<class traits>
void foo(Optimizer<traits>& self, const LMQN&) {
printf(" LMQN %lf\n", self.data.data);
}

template<class traits>
void foo(Optimizer<traits>& self, const CBFGS&) {
printf("CBFGS %d\n", self.data.data);
}

template<class traits = default_optimizer_traits>
class Optimizer {
friend class traits::update_type;
friend void dj::foo<traits>(Optimizer<traits>& self,
const typename traits::update_type&);
public:
void foo() {
dj::foo<traits>(*this, typename traits::update_type());
}
void bar() {
data.bar();
}
protected:
typedef typename traits::update_type update_type;
update_type data;
};

或者,如果您想针对不同的特征方便地将几个函数组合在一起,可能这样:

template<class traits, class updater=typename traits::update_type> 
struct OptimizerImpl;

template<class traits>
struct OptimizerImpl<traits, LMQN> {
static void foo(Optimizer<traits>& self) {
printf(" LMQN %lf\n", self.data.data);
}
};

template<class traits>
struct OptimizerImpl<traits, CBFGS> {
static void foo(Optimizer<traits>& self) {
printf("CBFGS %d\n", self.data.data);
}
};

template<class traits = default_optimizer_traits>
class Optimizer{
friend class traits::update_type;
friend struct OptimizerImpl<traits>;
public:
void foo() {
OptimizerImpl<traits>::foo(*this);
}
// ...
};

关于c++ - 由 traits [policies, actually] 实例化的类成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2641367/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com