繁体   English   中英

数据访问器类型的const正确性 - 更好的解决方案?

[英]const-correctness of data-accessor types - better solution?

我正在开发一个图像类,它可以处理具有不同像素布局(RGB,RGBA,灰色,拜耳等)的图像。 要访问像素,可以调用image.at<PixelType>(x,y) ,返回“访问者”。 具体的Accessor实现依赖于模板参数。 但是现在我遇到了一些关于const正确性的问题。

这是一个非常愚蠢的实现,希望它显而易见:

template<bool constAccessor>
class Accessor {
public:
    typedef typename boost::mpl::if_c<constAccessor, const int, int>::type DataType;

    Accessor(DataType& data) 
    :data(data) {
    }

    Accessor(Accessor<false>& other) 
    : data(other.data) {
    }

    DataType& data;
};


class Image {
public:
    Accessor<false> at(unsigned int x, unsigned int y) {
        return Accessor<false>(data);
    }
    Accessor<true> at(unsigned int x, unsigned int y) const {
        return Accessor<true>(data);
    }

private:
    int data;
};

int main() {
    Image img;
    const Image& cimg = img;

    // get accessor which is non-const
    Accessor<false> a1 = img.at(0, 0); 

    // get a accessor which is const...
    Accessor<true> a2 = a1;
    // ... modifying a value results in an error
    a2.data = 42;

    // try to convert a accessor which is const to a non-const version
    // ... results in an error
    Accessor<false> a3 = a2;

    return 0;
}

如您所见, at方法有一个非const和一个const实现。 根据constness,访问者的模板参数设置为truefalse 但是现在我有两种不同的类型(const和非const)每个访问器/像素类型,这使得有必要编写转换构造函数,因为否则main()函数中显示的测试用例将无法工作。

现在的问题是:有没有更好的方法来实现这一目标? 使用模板参数作为const指示器感觉有点不好。 使用Accessorconst Accessor会好得多。 另一方面,这类似于std-library对::iterator::const_iterator 任何人都有这种情况的经验吗?

你可以(过度)将参数从两个布尔状态推广到任何值类型:

template<typename Value>
class Accessor {
public:    
    Accessor(Value& data) 
        : data(data)
    {}

    template<typename T, EnableIf<std::is_convertible<T&, Value&>>...>
    Accessor(Accessor<T> const& other)
        : data(other.data)
    {}

    Value& data;
};

显然这与你所拥有的没什么不同,除了另一种形式:不是Accessor<false>Accessor<true> ,你有Accessor<DataType>Accessor<DataType const>

好处是熟悉:所有例如std::unique_ptr<T>std::shared_ptr<T>std::reference_wrapper<T> (甚至T* )的行为方式相同。 特别是,这种家庭化应该有希望扩展到编译器错误,即从Accessor<DataType const>Accessor<DataType>的转换不足,就像你不能从int const*转换为int*

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM