编写很多类型别名是不好的做法?

时间:2012-07-30 19:09:37

标签: c++

我发现自己编写了很多类型别名(typedef)来使代码更容易更改,但同时有些东西告诉我要避免这样做,因为它会给那些打算使用它的人带来很多困惑。 /在我的代码上。

也许不是最好的例子,但看看here。我还会举一个最近的例子;这些是我在构建XML解析器时弄乱的一些类:

namespace XML
{
    struct Attribute
    {
        typedef std::string name_t;
        typedef std::string value_t;

        Attribute(const name_t &name, const value_t &value = "");

        name_t name;
        value_t value;
    };
}

namespace XML
{
    class Element
    {
        private:
            typedef std::list<Attribute> attribute_container;
            typedef std::list<Element> element_container;

        public:
            typedef attribute_container::iterator attribute_iterator;
            typedef attribute_container::const_iterator const_attribute_iterator;

            typedef element_container::iterator element_iterator;
            typedef element_container::const_iterator const_element_iterator;

            typedef std::string name_t;
            typedef std::string data_t;
...
        private:
            name_t _name;
            data_t _data;

            attribute_container _attributes;
            element_container _child_elements;

以这种方式做事会使编写代码变得更容易,也许它会让它更直观但是这种做法的缺点是什么?

4 个答案:

答案 0 :(得分:5)

这是我的5美分。你只需要在某些情况下制作那些typedef。例如,如果您正在编写自己的迭代器类,则必须使其与iterator_traits一起使用并提供嵌套的typedef,如difference_type等。在某些情况下,容器也适用。例如,如果某些常用函数是这样写的:

template <typename T>
void foo(T::iterator it);

然后无论T被指定为模板参数,它都必须声明嵌套的iterator类型。您可以引入自己的额外模板接口约定,并在整个代码中遵循它们。

嵌套类型有用的另一种情况是别名模板参数,让代码的其他部分引用它。例如:

template <typename T>
class Foo {
  public:
    typedef T now_you_can_access_this_from_the_outside;
};

但除此之外 - 不需要typedefing。然后这是一个偏好的问题,但我打赌我的房子 - std::stringvalue_t更具可读性,因为每个人都知道std::string是什么,value_t什么都不告诉关于自己。

答案 1 :(得分:2)

我的经验法则是,如果使用的typedef超过2-3次,则值得存在。 否则,这是墨水的浪费,这对环境不利。

答案 2 :(得分:1)

主观上,当正确完成时,这实际上使代码更容易阅读和理解。同样在std和扩展名boost中广泛使用,因此您可能只想保持一致。

答案 3 :(得分:1)

有效的编程是关于你可以适应的东西。如果定义一种类型可以更容易地适应你的头脑,那就去做吧。但如果你做得太多,跟踪太多类型的认知负担会对你造成伤害。

例如,我可能会使用一个:

typedef std::map<std::string, std::vector<std::string> > SynonymMap;

总结一下,你将为程序中的每个变量创建一个新类型。这有多可读?