gpt4 book ai didi

C++ 可链接属性

转载 作者:太空宇宙 更新时间:2023-11-04 12:02:31 28 4
gpt4 key购买 nike

我正在尝试创建一个相对类型安全(但动态)且高效的概念,称为“可链接属性”。可链接属性类似于 C# 绑定(bind)属性等的能力,类似于信号/槽模型。

可链接属性是一种可以将自身链接到其他类型的值的类型。当任何值更改时,所有值都会更新。当您需要同时更新多个属性/值时,这很有用。设置链接后,一切都会为您处理。

  1. 可以从任何类型链接到任何其他类型(理论上,这就是问题所在)
  2. 链接使用链表而不是列表。这在内存和速度方面都更加高效,也是使用这种方法的真正好处。
  3. 转换器用于将值从一种类型转换为另一种类型(从 1,必需,也是一个问题)
  4. 可以充当 getter 和 setter。

我正在努力解决的问题是编写链接和转换为任何类型的功能。以下代码稍作改动(将模板化的 Chain 函数转换为非模板化版本,并将 Chain<F> 函数中的 Chain 更改为 SetLink )。问题是链接没有被正确调用。

这个类几乎可以工作(它编译和运行但没有按预期工作。如果没有上述更改,绑定(bind)函数永远不会调用。它只是测试代码,没有正确编码(请不要评论使用静态计数器,这只是临时修复)。Chain 和 Link 元素是关键方面。

链只是假设转换和更新属性的值,然后将它(或可能是原始值)传递给下一个属性。这一直持续到返回到原始属性为止,在这种情况下它将终止。

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace std;



static int iLCount = 1;
template <typename T>
class LinkableProperty
{
public:
std::string Name;
boost::function<void(T)> Link;

T Value;

template<typename F>
void Chain(F val)
{
Value = val;
std::cout << this->Name << " - " << this << ", " << &Link << ", " << val << " ! " << this->Value << " - " << "\n";
if (--iLCount < 0) return;
if (!Link.empty()) Link(Value);
}


LinkableProperty() { Link = NULL; Value = T(); Name = "Level " + std::to_string(iLCount++); };

void operator =(T value) { Value = value; }

template<typename F> void SetLink(LinkableProperty<F> &p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<F>, &p, _1);
}

void operator ()()
{
if (!Link.empty()) Link(Value);
}

};



int main()
{

LinkableProperty<unsigned short> L1;
LinkableProperty<double> L2;

L2.SetLink(L1);
L1.SetLink(L2);

L1 = 1;
L2 = 1.1;

L1();

cout << "----------\n" << L1.Value << ", " << L2.Value << endl;
getchar();
return 0;
}

最佳答案

问题最有可能源于这里:

template<typename F> void SetLink(LinkableProperty<F> p)

您正在传递原始属性的拷贝。将其更改为接受引用(或指针),您的运气可能会好一些。例如:

template<typename F>
void SetLink(LinkableProperty<F>* p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<F>, p, _1);
}

应该按预期工作......

编辑:更新以显示如何在转换过程中保留类型:

template <typename FT, typename TT>
TT convert(FT v)
{
return v; // default implicit conversion
}

template<>
double convert(unsigned short v)
{
std::cout << "us->d" << std::endl;
return static_cast<double>(v);
}

template<>
unsigned short convert(double v)
{
std::cout << "d->us" << std::endl;
return static_cast<unsigned short>(v);
}

static int iLCount = 1;
template <typename T>
class LinkableProperty
{
template <typename U>
struct _vref
{
typedef U vt;
_vref(vt& v) : _ref(v) {}
U& _ref;
};
public:
std::string Name;
boost::function<void(_vref<T>)> Link;

T Value;

template<typename F>
void Chain(F const& val)
{
Value = convert<typename F::vt, T>(val._ref);
std::cout << this->Name << " - " << this << ", " << &Link << ", " << val._ref << " ! " << this->Value << " - " << "\n";
if (--iLCount < 0) return;
if (!Link.empty()) Link(Value);
}


LinkableProperty() { Link = NULL; Value = T(); Name = "Level " + std::to_string(iLCount++); };

void operator =(T value) { Value = value; }

template<typename F>
void SetLink(LinkableProperty<F>* p)
{
Link = boost::bind(&LinkableProperty<F>::template Chain<_vref<T>>, p, _1);
}

void operator ()()
{
if (!Link.empty()) Link(_vref<T>(Value));
}

};



int main()
{

LinkableProperty<unsigned short> L1;
LinkableProperty<double> L2;

L2.SetLink(&L1);
L1.SetLink(&L2);

L1 = 1;
L2 = 1.1;

L1();

cout << "----------\n" << L1.Value << ", " << L2.Value << endl;
getchar();
return 0;
}

注意:存在一些链接错误,这意味着更新触发的次数超出了必要的次数 - 您应该检查...

关于C++ 可链接属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13563873/

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