我正在尝试创建一个相对类型安全(但动态)且高效的概念,称为“可链接属性”。可链接属性类似于 C# 绑定属性的能力,并且类似于信号/插槽模型。
可链接属性是一种可以将自身链接到其他类型的值的类型。当任何值更改时,所有值都会更新。当您需要同时更新多个属性/值时,这很有用。设置链接后,一切都会为您处理好。
- 可以从任何类型链接到任何其他类型(理论上,这就是问题所在)
- 链接使用链表而不是列表。这在内存和速度上都更有效,并且使用这种方法的真正好处。
- 转换器用于将值从一种类型转换为另一种类型(从 1,必需,也是一个问题)
- 可以像 getter 和 setter 一样工作。
我正在努力解决的问题是编写链接和转换为任何类型的能力。以下代码进行了微小的更改(将模板化的 Chain 函数转换为非模板化版本并在函数中更改Chain<F>
为)。问题是,链接没有正确调用。Chain
SetLink
这个类几乎可以工作(它确实编译并运行但没有按预期工作。如果没有上面的更改绑定函数永远不会调用。它只是测试代码并且没有正确编码(请不要评论使用静态计数器,它只是临时修复)。链和链接元素是关键方面。
链只是假设转换和更新属性的值,然后将其传递(或可能是原始值)到下一个属性。这种情况一直持续到一个人回到原始财产,在这种情况下它将终止。
#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;
}