Using boost::optional with constant types - C++

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-12 12:46:21

问题


I have a container class which uses boost::optional to hold the value. Here is the code looks like,

template<typename T>
struct traits
{
    typedef T  value_type;
    typedef T& reference;
};

template<typename T>
struct traits<const T>
{
    typedef const T  value_type;
    typedef const T& reference;
};

template<typename T>
struct traits<T*>
{
    typedef T* value_type;
    typedef T* reference;
};

template<typename T>
struct traits<const T*>
{
    typedef const T* value_type;
    typedef const T* reference;
};

template<typename T>
class container
{
public:

    typedef typename traits<T>::reference reference;
    typedef typename traits<T>::value_type value_type;

    container() {}

    void set(reference value) {
        op.reset(value);
    }

    reference get() const {
        return boost::get(op);
    }

private:
    boost::optional<value_type> op;
};

int main()
{
    foo f;
    container<const foo> c;
    c.set(f);
    return 0;
}

It works well for other types except const. I am getting error when I use const types (const foo* works fine).

  1. Is boost::optional supports constant types? If no, how can I work around this issue?
  2. Is there a ready made traits implementation available which I can use rather than defining my own traits?

Any help would be great!


回答1:


The problem is not with boost::optional, but with the logic of what you're trying to do. First you create a container of const, and then you try to modify what's contained. I would be surprised if that worked.

I think you should probably do what standard containers (like vector) do and forbid non-copyable template arguments.

Otherwise you'll have to live with the fact that your set method won't work when T is non-copyable, and provide a constructor that performs the initialization:

class container
{
public:

    container(reference init_value) : op(init_value) {}

};

int main()
{
    foo f;
    container<const foo> c(f);  // OK
    //   c.set(f);  NO
    return 0;
}



回答2:


template<typename T>
struct traits
{
    typedef T  value_type;
    typedef T& reference;
};

template<typename T>
struct traits<const T>
{
    typedef const T  value_type;
    typedef const T& reference;
};

Isn't the const specialization completely pointless? Without the specialization, traits<const int> will have const int as the value_type and const int& as the reference, which is exactly what you tried to achieve with the const specialization, right?



来源:https://stackoverflow.com/questions/2306645/using-boostoptional-with-constant-types-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!