C ++可链接属性 [英] C++ Linkable Properties

查看:118
本文介绍了C ++可链接属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to create a relatively type safe(but dynamic) and efficient concept called "Linkable Properties". A linkable property is similar to C#'s ability to bind properties and such and similar to the signal/slot model.

可链接属性是一种类型,可以将自身链接到值的其他类型。当任何值更改时,所有值都更新。当您需要同时更新多个属性/值时,这是非常有用的。一旦你设置了链接,一切都照顾你。

A linkable property is a type that can link itself to the values of other types. When any value changes all values are updated. This is useful when you need to keep several properties/values updated simultaneously. Once you setup a link everything is taken care of for you.


  1. 可以从任何类型链接到任何其他类型问题)

  2. 链接使用链接列表而不是列表。

  3. 转换器用于将值从一种类型转换为另一种类型(从1开始,必需,也是一个问题)

  4. 可以充当getter和setter。

  1. Can link from any type to any other type (in theory, this is the issue)
  2. Links use a linked list rather than a list. This is more efficient both memory and speed and the real benefit of using this approach.
  3. Converters are used to convert the values from one type to another(from 1, required, also an issue)
  4. Can act like a getter and setter.

我努力的问题是编写链接和转换为任何类型的能力。以下代码适用于较小的更改(将模板链函数转换为非模板版本,并将 Chain 转换为 SetLink 函数)。问题是,链接未正确调用。

The issues I'm struggling with is writing the ability to link and convert to any type. The following code works with minor changes(convert the templated Chain function to a non-templated version and Change Chain<F> to Chain in the SetLink function). The problem is, the links are not correctly called.

这个类几乎工作(它编译和运行,但不能按预期工作。从来没有调用,它只是测试代码和没有正确编码(请不要评论使用静态计数器,它只是一个临时修复)。链和链接元素是关键的方面。

This class almost works(it does compile and run but does not work as expected. Without the changes above the binding function never calls. It is only test code and not properly coded(please don't comment about using the static counter, it's just a temporary fix). The Chain and Link elements are the crucial aspect.

Chain只是简单地假设转换和更新属性的值,然后将它(或可能原始值)传递给下一个属性。这继续,直到一个回到原始属性,在这种情况下

Chain is simply suppose to convert and update the value of the property then pass it along(or possibly the original value) to the next property. This continues until one reaches back to the original property in which case it will terminate.

#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)

您正在传递原始资源的副本。改变这个接受一个引用(或指针),你可以有更好的运气。例如:

You are passing in a copy of the original property. Change this to accept a reference (or pointer), and you may have better luck. For example:

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

应按预期工作...

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

Updated to show how to preserve the type across the conversion:

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;
}

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

NOTE: There is some link bug which means that the updates trigger more times than necessary - you should check that...

这篇关于C ++可链接属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆