typedef 复杂 STL 映射时的命名约定是什么?

发布于 2024-07-17 05:03:30 字数 791 浏览 4 评论 0原文

时,实践中使用的约定是什么

1) 当 typedef类似的东西

typedef std::map<SomeClass*, SomeOtherClass>  [SomeStandardName>]
typedef std::map<SomeClass*, std<SomeOtherClass> >  <[SomeStandardName]

2) 你通常把 typedef: 头文件放在全局的、本地的类的哪里?

3)你输入def iterators还是const map<> 版本?

4)假设您有两个不同概念使用的地图,您是否为它们创建两个单独的 typedef?

typedef map<string, SomeClass *> IDToSomeClassMap;
typedef map<string, SomeClass *> DescriptionToSomeClassMap;

谢谢


编辑 #1

我对 typedef STL 映射特别感兴趣,例如

typedef map<int, string> IdToDescriptionMap

typedef map<int, string> IdToDescription

常见做法是什么?

1) What is the convention used in practice when typedef'ing

something like

typedef std::map<SomeClass*, SomeOtherClass>  [SomeStandardName>]
typedef std::map<SomeClass*, std<SomeOtherClass> >  <[SomeStandardName]

2) Where do you usually put typedef: header files globally, local to the class?

3) Do you typedef iterators or const map<> version?

4) Say you have map that used by two different concepts, do you create two separate typedefs them?

typedef map<string, SomeClass *> IDToSomeClassMap;
typedef map<string, SomeClass *> DescriptionToSomeClassMap;

Thanks


Edit #1

I am interested specifically in typedef STL maps, such as

typedef map<int, string> IdToDescriptionMap

or

typedef map<int, string> IdToDescription

What are common practices?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

巴黎盛开的樱花 2024-07-24 05:03:30

我更喜欢以下约定:

typedef std::map< Foo, Bar > FooToBarMap

我故意避免对迭代器进行类型定义,我更喜欢将它们显式引用为:

FooToBarMap::const_iterator

因为迭代器已经是事实上的标准类型名。 我发现,在浏览代码时,FooToBarMapConstIter 实际上不太清晰。

I prefer the following convention:

typedef std::map< Foo, Bar > FooToBarMap

I purposely avoid typedef'ing the iterators, I prefer explicitly referring to them as:

FooToBarMap::const_iterator

Since the iterators are already a de facto standard typename. And FooToBarMapConstIter is actually less clear to read when skimming code, I find.

知你几分 2024-07-24 05:03:30

对于这些名称没有普遍同意的规则。 我通常做的就是使用以Map为后缀的“值”类的名称。 在您的示例中,这将是 SomeOtherClassMap。 我使用此约定是因为通常更有趣的是,您的映射包含 SomeOtherClass 类型的“值”对象,然后使用 SomeClass 的“键”查找它们。

There is no generally agreed rule on these names. What I usually do is to use the name of the "value" class suffixed with Map. In your example that would be SomeOtherClassMap. I use this convention because it is usually more interesting that your map contains "value" objects of type SomeOtherClass then that you look them up with "keys" of SomeClass.

她如夕阳 2024-07-24 05:03:30

问题的第二部分对我来说是最有趣的部分。 当有合适的位置时,我更喜欢将 typedef 放在使用它们的类中,即使它们在其他类中使用。 但这会导致前向声明出现一些问题(我们大量使用前向声明来提高编译速度)。

例如,在最近的一个项目中,我们有一个名为 Io 的类,其中嵌入了名为 Point 的 typedef,这使得代码非常可读 - 一个 Io:: Point 非常清晰易读。 但是每当我们想要使用该类型时,我们都必须包含 Io 类的声明,即使我们需要的只是 Io::Point 的声明,因为(据我所知)无法转发声明类中的类型。

在这种情况下,我们最终采取了两种方法。 我们创建了一个全局 IoPoint 类型,然后对其进行 typedefd Io::Point (这样我们已经编写的代码就没有待修改)。 这不是最漂亮的答案,但它完成了工作。

至于其他部分:

我们不使用任何特殊的命名约定。 对于地图,我们经常使用 *DescriptiveSomething***Map** (因为我们不太可能从地图更改为其他容器类型),但是如果 DescriptiveSomething 具有足够的描述性并且不'如果不与现有名称冲突,我们通常会使用它。

我们通常不会为迭代器创建 typedef,因为只需使用 Type::iteratorType::const_iterator 就很容易(而且非常易读)。 也就是说,如果类型名称太长,Type::const_iterator 会使代码看起来太“笨重”,我们有时会使用 typedef 来定义它们。 (不知道有什么更好的表达方式,但您可能知道我的意思。)

我们为每个概念创建不同的 typedef,即使其中两个定义完全相同的类型。 它们可以相互独立地更改,因此为它们使用不同的类型名称可以简化以后的重构。 在许多情况下,它还可以使代码更具可读性。

The second part of the question is the most interesting one to me. I prefer to put typedefs within the classes that use them, when there's a logical place for them, even if they're used in other classes. But that causes some problems with forward declarations (which we use heavily for compile-speed).

For example, in one recent project we had a class called Io, with an embedded typedef called Point, which made for very readable code -- an Io::Point is very clear and readable. But whenever we wanted to use the type, we had to include the declaration of the Io class, even if all we needed was the declaration of Io::Point, since there's no way (that I know of) to forward-declare a type that's within a forward-declared class.

In that case, we ended up doing it both ways. We created a global IoPoint type, and then typedefd Io::Point to it (so that our already-written code didn't have to be modified). Not the prettiest answer, but it got the job done.

As for the other parts:

We don't use any special convention for the names. For maps, we often use *DescriptiveSomething***Map** (since it's unlikely that we'll ever change from a map to some other container type), but if DescriptiveSomething is descriptive enough and doesn't conflict with an existing name, we'll often use it instead.

We generally don't bother creating typedefs for the iterators, since it's easy (and very readable) to simply use Type::iterator or Type::const_iterator. That said, we do sometimes typedef them if the type name is so long that Type::const_iterator makes the code look too "chunky." (Don't know of any better way to say it, but you probably know what I mean.)

We create different typedefs for each concept, even if two of them define exactly the same type. They can change independent of one another, so having different type names for them simplifies any later refactoring. It also makes for more readable code, in many cases.

怎樣才叫好 2024-07-24 05:03:30

我不知道该主题是否有任何正式规则,但我通常在最适合项目中使用的位置添加类型定义。

  • 如果 typedef 仅在一个类中使用,则将 typedef 添加到类定义中
  • 如果 typedef 被多个不相关的类使用,则将其添加到命名空间范围级别的头文件中

至于 typedef 类型的实际名称。 我将其命名为对 typedef 有意义的任何名称。 我不会给 typedef 名称任何特殊约定,例如使用 _t 前缀或类似的任何内容。 例如

typedef stl::map<stl::string,Student> NameToStudentMap;

I don't know if there are any formal rules on the subject but I usually add type defs at the location most befitting the use within the project.

  • If the typedef is only used within one class then add the typedef inside the class definition
  • If the typedef is used by several unrelated classes add it in a header file at a namespace scope level

As for the actual name of the typedef'd type. I name it whatever makes sense for the typedef. I don't give typedef names any special convention such as prefixing with _t or anything along those lines. For example

typedef stl::map<stl::string,Student> NameToStudentMap;
节枝 2024-07-24 05:03:30

没有,只需记住命名标识符的一般规则(没有 _ 开头等)。 此外,如果您的组织有编码指南,最好遵守它。

通常,当定义您自己的模板类时,如果没有 typedef,它会变得混乱——所以我会在那里创建它们作为方便的快捷方式。 但是,如果它确实是一堆类,我宁愿将其放在命名空间级别。

None, just keep in mind the general rules for naming identifiers (no _ to begin with etc). Also, if your organization has a coding guideline, it is best to stick to it.

Often, when defining your own template class, it becomes messy without typedefs -- so I'd create them there as handy shortcuts. However, if it's really a bunch of classes, I'd rather have it at namespace level.

心的憧憬 2024-07-24 05:03:30

我们在工作场所使用以下内容:

typedef std::map WhateverMap;
typedef WhateverMap::iterator WhateverIter;
typedef WhateverMap::const_iterator WhateverCIter;

就地点而言,情况各不相同。 如果它是特定于类的,则它可能位于 Impl 结构中,或者可能位于类声明的受保护或私有区域中。 如果它更通用(跨文件使用,在 API 中使用),我们将其放在单独的“FooTypes.h”样式标头中。

请注意,由于我们有时会更改基础类型,因此我们可以使用“WhateverCollection”而不是“WhateverVec”或“WhateverList”。 根据所需的占用空间和性能特征,将“WhateverList”实际上定义为向量或列表的情况并不罕见。

We use the following at my workplace:

typedef std::map WhateverMap;
typedef WhateverMap::iterator WhateverIter;
typedef WhateverMap::const_iterator WhateverCIter;

As far as location goes, that varies. If it's class-specific, it may be in an Impl structure, or may be in the protected or private areas of the class declaration. If it's more general (used across files, used in an API), we put it in a separate "FooTypes.h" style header.

Note that since it's common for us to sometimes change the underlying type, we may use "WhateverCollection" instead of "WhateverVec" or "WhateverList". It's not uncommon to have a "WhateverList" actually be typedefed to a vector or an slist, depending on desired footprint and performance characteristics.

不美如何 2024-07-24 05:03:30

兴趣问题:
我查看了 boost,发现它们没有任何全局规则,但大多数使用约定

typedef std::map< key, value > some_domain_specific_name_map;

typedef std::map< key, value > some_domain_specific_name_map_type;

良好实践来为 value_type 或迭代器创建 typedef,通常它们与 map 具有相同的名称,但以 _value_type、_iterator 结尾。

Interest question:
I looked in boost, and I see they haven't any global rule, but most used convention

typedef std::map< key, value > some_domain_specific_name_map;

or

typedef std::map< key, value > some_domain_specific_name_map_type;

also good practice to make typedef for value_type or iterators, usually they have same name as map but with ending _value_type, _iterator.

时光是把杀猪刀 2024-07-24 05:03:30

通常我会定义与 typedef 相关的名称来指示对象的类型。

例如:

typedef std::vector<ClassCompStudent*> StudentCollection;

typedef std::map<std::string /*id*/, ClassCompStudent* /*pStudent*/>  IDToStudentMap;

此外,我在创建对象的类标头中将它们定义为公共。 这给了我在不破坏客户端代码的情况下更改容器类型的好处。

class Test
{
public:
    typedef std::vector<ClassCompStudent*> StudentCollection;

    /* Users of Test need not know whether I use vector or list for 
        storing students. They get student collection and use it*/
    bool getStudents(StudentCollection& studentList) const;

    void print()
    {
        //do printing
    }
private:

    StudentCollection m_StudentList;
};

bool function(const Test& testObj)
{
    //If StudentCollection gets changed to list, this code need not be changed.
    StudentCollection aCollection;
    testObj.getStudents(aCollection);
    std::for_each(aCollection.begin(), aCollection.end(), std::mem_fun(&Test::print));
}

Normally I define related name to the typedef indicating the type of the object .

Ex:

typedef std::vector<ClassCompStudent*> StudentCollection;

typedef std::map<std::string /*id*/, ClassCompStudent* /*pStudent*/>  IDToStudentMap;

Also, I define them as public in class header in which the object has been created. That gives me the benefit of changing the container type without breaking client code.

class Test
{
public:
    typedef std::vector<ClassCompStudent*> StudentCollection;

    /* Users of Test need not know whether I use vector or list for 
        storing students. They get student collection and use it*/
    bool getStudents(StudentCollection& studentList) const;

    void print()
    {
        //do printing
    }
private:

    StudentCollection m_StudentList;
};

bool function(const Test& testObj)
{
    //If StudentCollection gets changed to list, this code need not be changed.
    StudentCollection aCollection;
    testObj.getStudents(aCollection);
    std::for_each(aCollection.begin(), aCollection.end(), std::mem_fun(&Test::print));
}
彡翼 2024-07-24 05:03:30

以无用的符号形式使用“地图”或“矢量”一词。 这些词与实现有关,与商业模式无关。

您不必表明该类型是矢量或地图。 您可以使用列表。 就像

typedef std::vector<std::string> List;
typedef std::set<std::string> List;

这两个都是字符串列表。 这是真的。

typedef std::map<std::string, Object> List;
or  
typedef std::map<std::string, Object> NamedList;

我的观点是不要使用匈牙利符号。

Using word "Map" or "Vector" in kind of useless notation. These are words connected to realization and not to the business model.

You don't have to show that this type is vector or map. You can use List. Like

typedef std::vector<std::string> List;
typedef std::set<std::string> List;

These both are lists of string. And this is true.

typedef std::map<std::string, Object> List;
or  
typedef std::map<std::string, Object> NamedList;

My point is don't use kind of hungarian notation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文