【问题标题】:Using boost::optional with constant types - C++使用带有常量类型的 boost::optional - C++
【发布时间】:2010-02-21 17:12:40
【问题描述】:

我有一个容器类,它使用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. 是否有现成的可用特征实现可供我使用,而不是定义我自己的特征?

任何帮助都会很棒!

【问题讨论】:

  • const foo* 当然不是 const 类型。 foo* const 是。

标签: c++ templates boost const-correctness


【解决方案1】:

问题不在于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 我同意你对他的代码的批评。我删除了我的答案,因为我发现我正在教授危险的练习。如果容器的用途是我们都怀疑的,那么我同意你的回答。
  • @Manuel:我并没有真正尝试添加不同级别的间接。我迷失在模板世界中。我有一个 tree_node ,它保存一个值作为键。值将存储在optional。每当我尝试使用不同类型的节点时,它都会出错并且无法使其适用于所有类型。
  • @Appu - 你正在做的事情很棘手,如果你没有丰富的 C++ 经验,遇到麻烦是很正常的。我很好奇,是什么让你觉得你需要使用optional
  • @Manuel:请看我的另一个问题。 stackoverflow.com/questions/2274817/… 。我已经解释了为什么我开始使用 optional。
  • @Appu - 听起来像是boost::optional 的合理应用。我的建议是你忘记所有这些疯狂的特征,如果用户想要存储指针,那么 reference 类型应该是对指针的引用,这没有错。顺便说一句,这就是 STL 容器的工作方式
【解决方案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;
};

const 专业化不是完全没有意义吗?如果没有专业化,traits&lt;const int&gt; 将有 const int 作为 value_typeconst int&amp; 作为 reference,这正是您试图通过 const 专业化实现的目标,对吧?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-02
    • 2011-06-05
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    • 2014-04-09
    相关资源
    最近更新 更多