【问题标题】:Naming a typedef for a boost::shared_ptr<const Foo>为 boost::shared_ptr<const Foo> 命名 typedef
【发布时间】:2010-05-17 18:06:01
【问题描述】:

愚蠢的问题,但说你有 Foo 类:

class Foo
{
public:
    typedef boost::shared_ptr<Foo> RcPtr;

    void non_const_method() {}
    void const_method() const {}
};

拥有 const Foo::RcPtr 不会阻止在类上调用非 const 方法,以下将编译:

#include <boost/shared_ptr.hpp>

int main()
{
    const Foo::RcPtr const_foo_ptr(new Foo);
    const_foo_ptr->non_const_method();
    const_foo_ptr->const_method();

    return 0;
}

但是命名一个 typedef ConstRcPtr 对我来说意味着 typedef 是

typedef const boost::shared_ptr<Foo> ConstRcPtr;

这不是我感兴趣的。一个更奇怪但可能更准确的名字是 RcPtrConst:

typedef boost::shared_ptr<const Foo> RcPtrConst;

但是,谷歌搜索 RcPtrConst 的命中率为零,因此人们不会将其用作 typedef 名称 :)

还有人有其他建议吗?

【问题讨论】:

    标签: c++ boost shared-ptr


    【解决方案1】:

    typedef 的名称不代表用于定义其类型的语法结构。 typedef 名称应该传达一些它想要的含义。例如,标准将 const T 上的迭代器的名称定义为 const_iterator,即使迭代器本身不是 const(您仍然可以递增它)。事实上,迭代器的全部目的是改变它,以便迭代一个序列:)

    typedef T const* const_iterator;
    

    对于指针,我个人认为没有理由一般将它们定义为常量。因此,尾部前面的Const 可以传达与迭代器相同的含义,并且将与现有实践相一致。所以我觉得你去说完全没问题

    typedef boost::shared_ptr<Foo const> ConstRcPtr;
    

    事实上,std::allocator&lt;&gt;::const_pointer 也是这样写的。

    【讨论】:

    • "诚然,标准库包含 const_iterator 的概念,即不可原谅,一个引用常量元素的迭代器;迭代器本身不是常量。(只是因为标准委员会有一个糟糕的一天并不意味着你应该效仿他们。)”——Stephen C. Dewhurst C++ Gotchas
    • @tod 恕我直言,这不是一个坏主意
    【解决方案2】:

    您关于 const 去向的陈述是正确的:您需要另一个 typedef。在我们的项目中,我们使用 Foo::TPtrFoo::TConstPtr 作为标准类型定义。

    【讨论】:

      【解决方案3】:

      命名 typedef ConstRcPtr 对我来说意味着 typedef 将是 typedef const boost::shared_ptr&lt;Foo&gt; ConstRcPtr;

      为什么会这样?当人们谈论“const 指针”(相对于非常量指针)时,他们几乎总是指的是const char*,而不是char *constconst_iterator 是一个迭代器到常量,而不是一个常量迭代器,我一点也不惊讶ConstRcPtrRcPtr 之间的关系与const_iterator 和@987654328 之间的关系相同@。

      如果您需要区分const char*char *const,那么可以,您可以将char *const 称为“常量指针”,将const char* 称为“常量指针”。但是您几乎从不这样做,因此短语“const pointer”用于常见情况。我认为这也适用于这里,除非您打算 typedef 所有四个:

      boost::shared_ptr<Foo>
      boost::shared_ptr<const Foo>
      const boost::shared_ptr<Foo>
      const boost::shared_ptr<const Foo>
      

      在这种情况下,你必须在名字方面更有创意。

      【讨论】:

      • 我不打算对 const boost::shared_ptr 本身进行 typedef,因为这可以在使用 typedef 的地方完成。我需要 const Foo 作为参数类型来指示该方法不会修改指向的对象。
      • “通俗地说,许多程序员将指向常量数据的指针称为“常量指针”。这不是一个好主意,因为它只会向无知的人传达正确的含义(指向常量数据的指针),并且会误导任何有能力的 C++ 程序员都会接受你的话(一个指向非常量数据的常量指针)。” - Stephen C. Dewhurst C++ 陷阱 I'm through quoting now I promise, I was just rereading this section of his book the day before I came across this discussion and couldn't resist.
      • @Tod:我认为 Stephen C. Dewhurst 错了。我同意如果人们总是说“指向常量的指针”,并且如果 const_iterator 被称为 iterator_to_const 会更清楚。我显然不是一个无知的人,因为我知道这个问题。所以我不同意他的说法,即只有无知的人才能理解那些不准确的短语在实践中的含义。当他声称没有称职的 C++ 程序员能够理解这些术语时,我还怀疑他有点不诚实。我认为他不小心把他的“某人错了在互联网上!”在书中咆哮。
      • +1 对你的回应,但在他的辩护中,他确实指定了一个称职的程序员,“相信你的话”。我认为他想尝试回到字面意思,但到 2003 年(版权日期)我怀疑惯用语已经根深蒂固。我是 smart ptrs 的新手,并且正在为 typedef 命名而苦苦挣扎,这对我来说听起来像是匈牙利口音,而且我倾向于在名称中没有“ptr”或“const”。
      • 我当然同意他的观点,将指针指向 const 称为“const 指针”不是一个好主意,因为这是一个字面意思不同的短语。但它已经变得足够普遍,可以理解了。我不同意他的观点,即调用 iterators-to-const const_iterator 是不可原谅的(甚至是错误的),因为这是该标准定义的一个标记,其他人不应该将 const vector&lt;int&gt;::iterator 称为const_iterator.
      猜你喜欢
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 2013-09-24
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多