【发布时间】:2020-01-05 11:41:41
【问题描述】:
对于我的项目,我使用了一些非常复杂的数据结构,例如
std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>
为了便于阅读,我想声明类型别名。我构建项目的代码已经通过在头文件中全局放置using 语句来做到这一点:
// bar.h
#ifndef BAR_H
#define BAR_H
#include <unordered_map>
#include <list>
#include <memory>
#include "foo.h"
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
class Bar {
FooTable create_foo();
};
#endif
由于我的 C++ 知识有点生疏,所以我只是采用了这种风格 - 但现在我读到以这种方式使用 using 可能会出现问题,因为它会在包含此标头的所有内容上强制使用此别名。
尽管进行了大量的谷歌搜索,但我找不到关于如何正确处理此问题的具体答案,只有很多关于不该做什么的陈述。所以,我只是把 using 放在类中:
// bar.h
#ifndef BAR_H
#define BAR_H
#include <unordered_map>
#include <list>
#include <memory>
#include "foo.h"
class Bar {
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
FooTable create_foo();
};
#endif
但是这有一个缺点,我需要在源文件中重新声明别名:
// bar.cpp
#include "bar.h"
using FooTable = std::unordered_map<int, std::list<std::shared_ptr<const Foo>>>;
FooTable Bar::create_foo()
{
...
}
虽然这似乎可行,但我不确定这是否安全……我的直觉告诉我这有点难看。所以在我像这样重写我的整个项目之前,我想我会问:有没有更好/更优雅/更安全的方法来做到这一点?还是应该完全避免在头文件中使用类型别名?
【问题讨论】:
-
我从不在全球范围内这样做;仅在类或命名空间内。好像这样污染更小。另外,由于我是老派,我倾向于使用
typedef。 -
你不需要在源文件中重新定义类型,只需要记住
FooTable的作用域在Bar类中。所以你需要指定,如Bar::FooTable Bar::create_foo() -
@Someprogrammerdude 你应该对此做出回答。
-
如果你有一个命名空间,你几乎可以选择。就我个人而言,我选择哪一个是有意义的(例如,如果 typedef 专门用于该类,我将它放在一个类中,如果它在其他地方使用而没有与特定类的连接,我将它放在命名空间中)。此外,您无需“重新声明”,只需使用
Bar::FooTable调用它即可。 -
你还应该将你的函数定义为:auto Bar::create_foo() -> FooTable 或类似的东西:-)
标签: c++ scope using-directives type-alias