使用boost::optional与常量类型 - C++

3

我有一个容器类,它使用boost::optional来保存值。下面是代码样例:

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

对于除了const之外的其他类型,它都工作正常。当我使用const类型(const foo*可以正常工作)时,我会遇到错误。

  1. boost::optional是否支持常量类型?如果不支持,我该如何解决这个问题?
  2. 是否有现成的traits实现可用,我可以使用而不是定义自己的traits?

任何帮助都将是极好的!


const foo* 当然不是 const 类型,foo* const 才是。 - MSalters
2个回答

4
问题并不在于boost :: optional ,而在于您尝试执行的逻辑。首先,您创建了一个const容器,然后尝试修改其内容。如果可以工作,我会感到惊讶。
我认为您应该像标准容器(如 vector )那样禁止不可复制的模板参数。
否则,当T是不可复制时,您将不得不接受您的 set 方法无法使用,并提供执行初始化的构造函数:
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;
}

+1 我同意你对他的代码的批评。我删除了我的回答,因为我发现我在教授危险的做法。如果容器的目的是我们所怀疑的那样,那么我同意你的答案。 - Johannes Schaub - litb
@Manuel:我并不是在尝试添加不同级别的间接性。我迷失在模板世界中了。我有一个tree_node,它将一个值作为键进行保存。该值将存储在“optional”中。每当我尝试使用不同类型的节点时,就会出现错误,并且无法使其适用于所有类型。 - Navaneeth K N
@Appu - 你正在做一件棘手的事情,如果你对C ++没有太多经验,那么遇到问题是很正常的。我很好奇,是什么让你觉得需要使用“optional”? - Manuel
@Manuel:请看一下我的另一个问题。https://dev59.com/uEzSa4cB1Zd3GeqPiwOw 。我已经解释了为什么开始使用可选项。 - Navaneeth K N
@Appu - 似乎是使用 boost::optional 的合理应用。我的建议是,如果用户想要存储指针,那么 reference 类型应该是指向指针的引用,忘记所有这些特性的疯狂吧,这没有任何问题。顺便说一下,这就是 STL 容器的工作方式。 - Manuel
@Manuel:让我试试。谢谢你的帮助。我非常感激。 - Navaneeth K N

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

这个 const 特化有完全没有意义吗?如果没有特化,traits<const int> 将会把 value_type 设为 const int,而 reference 设为 const int&,这不正是你想通过 const 特化来实现的吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接