2012-07-30 71 views
4

我發現自己編寫了很多類型別名(typedefs)來使代碼更易於更改,但同時也有一些東西讓我避免這樣做,因爲它可能會爲將要使用/在我的代碼上。編寫大量類型別名是不好的做法嗎?

也許不是最好的例子,但看看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; 

處事這樣可以更容易地編寫代碼,也許它使得有些直觀的,但什麼是這種做法的缺點?

+2

它增加了間接的級別,這樣讀取代碼的人就不得不看兩件事而不是一件事。是不是真的值得嗎?有經驗的C++開發人員會立即識別'std :: list '。 – 2012-07-30 19:12:29

+0

@RobertHarvey:是的,但另一方面是,如果代碼曾經想要使用不同的容器,那麼在容器上創建迭代器的每個地方都需要進行更改(例如)。 – jxh 2012-07-30 19:15:07

+2

如果它有幫助,它是好的,否則它是不好的。摩擦是知道的區別。例如,混淆字符串就會讓我煩惱。 – Duck 2012-07-30 19:15:15

回答

1

有效的編程是關於什麼你可以適應你的頭。如果定義一種類型可以更容易地融入你的頭部,那就去做吧。但是,如果你做得太多,追蹤太多類型的認知負擔會對你造成整體傷害。

比如我可能會使用一個這樣的:

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

帶到它的結論,你會發明瞭程序中的每個變量一個新類型。那會是多麼可讀?

+0

好點!爲每個新變量創建一個類型並不是一件好事。 – 2012-08-01 20:14:03

1

主觀上,當這樣做時,這實際上使代碼更易於閱讀和理解。同樣在std和擴展boost這是廣泛使用,所以你可能想要做的只是保持一致。

2

我的經驗法則是,如果typedef使用超過2-3次,那麼它是值得的。 否則,這是浪費墨水,這是對環境不利。

+5

您使用墨水進行編程?... – 2012-07-30 19:18:57

+0

這是什麼問題? – 2012-07-30 19:21:49

+1

我想它會降低開發速度。 :P – 2012-07-30 19:23:14

5

這是我的5美分。你只需要在某些情況下進行這些typedef。例如,如果您正在編寫自己的迭代器類,則必須使其與iterator_traits一起工作,並提供嵌套類型定義,如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也沒有提到自己。

相關問題