1

作为几个较大项目的一部分,我正在开发一个矩阵模板类,该类仅在块中元素的值从定义的初始值设定项值更改时动态分配块。这个类将用于一些相当复杂的数学,所以我试图让界面尽可能简单和直观。我希望能够使用 operator(row, col) 通过引用而不是使用 get(row, col) 和 set(element) 方法来访问矩阵元素。

然而,这变得有问题,因为由于分配行为,set 和 get 的操作需要不同,并且需要根据初始化程序值测试设置的值。这不能仅仅返回一个引用来完成,所以我创建了一个包含引用并且可以转换为正确的数据类型并返回它的帮助类。这是接口的结构:

template <class T>
class Container{

public:

    // Element class which contains a reference to a data element
    class Element{

    public:

        // Constructor -- Initialize the element reference
        Element(T & element) :  _element(element){}

        // Assignment operator -- SET
        Element & operator=(const T & that){
            _element = that;
            return *this;
        }

        // Element to element assignment -- GET that, SET this
        Element & operator=(const Element & that){
            this->_element = that._element;
            return *this;
        }

        // Implicit conversion operator -- GET
        operator T(){
            return _element;
        }

    private :

        T & _element; // Element reference

    };

    // Return an element class containing a reference to the element
    Element operator()(int index){
        return Element(_data[index]);;
    }

private:

    T _data[10];

};

它依赖于隐式转换才能使用返回的 Element 类,就好像它是类型 T不进行隐式转换,操作会导致编译器错误。而且我假设我会发现许多进一步的问题,试图将它与 T 一起用作类结构、指针等。

再加上依赖隐式转换来纠正类的功能似乎是非常糟糕的做法,这让我认为我需要想出另一种方法。有什么办法可以解决我目前的方法吗?我可能会采取其他一些方法吗?或者我应该放弃这一点,让 operator(row, col) 像往常一样分配 get 和 set 方法,只在必要时分配?

4

1 回答 1

0

你能为你做的魔法只有这么多。

我想首先向您指出Blitz++Thrust作为一些很好的教学示例。在第一种情况下,那些“魔术引用”被大量用于通过子数组访问数据区域等。第二种情况用于安全地访问来自其他内存空间(例如在 GPU 中)的数据,自动处理数据下载/上传。

我建议关注常见用法;您的容器是否主要用于保存标量值?然后只需提供常见的算术运算,例如 ++、+= 等,转发到实际实现。您会看到这是2中使用的方法。缺点是访问内部数据的成员有点不方便 - 但如果这是一种不常见的情况,那将是一个很好的权衡。

于 2012-07-31T20:23:03.583 回答