最近我在代码中遇到了以下构造:
typedef sometype sometype;
请注意“sometype”代表完全相同的类型,没有任何附加内容,如“struct”等。
我想知道它有什么用处?
UPD:这仅适用于用户定义的类型。
UPD2:实际代码在模板上下文中,如下所示:
template <class T>
struct E
{
typedef T T;
...
}
答案 0 :(得分:7)
如何使模板参数对外部实体可见?
template <class Foo>
struct Bar
{
typedef Foo Foo;
};
int main()
{
Bar<int>::Foo foo = 4;
}
注意:这在标准C ++中实际上是不允许的,但是特定于MSVC。见评论。
答案 1 :(得分:7)
鉴于您有关模板的其他信息,我们现在可以回答。
用例是指您想要专注于模板的类型。一个典型的例子如下:
template <typename T>
struct nonconst {
typedef T t;
};
template <typename T>
struct nonconst<T const> {
typedef T t;
};
这实际上允许您从任何类型中删除const
限定符:
nonconst<int>::t x;
nonconst<int const>::t y;
assert(typeid(x) == typeid(int));
assert(typeid(y) == typeid(int));
有许多类似的用例,例如从类型中添加(或删除)指针限定符,为某些类型提供默认值和特化等。
但是,会注意到类型名称的不同外壳! [我的立场更正:§7.1.3.2]此外,事实命名标准(在Boost库中使用它来巩固)是调用类型名称别名typedef T T
中的等同类型是非法的C ++。type
,例如:
typedef T type;
答案 2 :(得分:6)
在C ++中,您可以将typedef放在命名空间或类中,然后相对于该命名空间或类引用它,如果真实类型将来可能会发生变化,这将非常有用。
e.g。
class IntHolder
{
public:
typedef int int;
IntHolder::int i;
};
...
IntHolder foo;
IntHolder::int i = foo.i;
(注意:我没有检查过这是非常正确的语法 - 但希望你能得到这个想法)
如果在将来的某个时间点,您实际上想要在long
中保留IntHolder
,则只需更改IntHolder
代码。
现在,通常您会以不同的方式命名该类型,但也许您可以按上述方式进行操作?
答案 3 :(得分:6)
我有一个理论。这可能是一些重构的结果。例如,模板化类型不会模板化。
typedef SomeCleverTemplate<Rocket> SuperThing;
然后他们删除了模板,因为代码中没有其他用法,为了安全起见,他们将SomeCleverTemplate<Rocket>
替换为SuperThing
。
typedef SuperThing SuperThing;
在真实环境中是否有意义?
答案 4 :(得分:1)
正如已经提到的那样,它在模板中特别有效:
template <class Foo>
struct Bar
{
typedef Foo Foo;
};
但它也可以与模板专业化相结合:
template <class Foo>
struct Bar<Foo*>
{
typedef Foo Foo;
};
现在,我可以这样做:
Bar<int>::Foo i = 0;
Bar<int*>::Foo j = i;
Bar
因此有效地表现为一种类型的包装器,它对于它的接口可能很重要(例如,如果有bool equals(Foo i) const
)。
通常,当选名称具有某种含义value_type
,例如......
答案 5 :(得分:0)
新想法!某些编程俱乐部如广泛使用typedef ...
<强>动物园/只动物/ types.h中强>:
namespace zoo
{
namespace animals
{
typedef size_t Count;
// ...
} // namespace animals
} // namespace zoo
<强>动物园/只动物/ zebra.h 强>:
#include "zoo/animals/types.h"
namespace zoo
{
namespace animals
{
class Zebra {
public:
typedef Count Count;
Count getLegCount() const;
// ...
}; // class Zebra
} // namespace animals
} // namespace zoo
<强>的main.cpp 强>:
#include "zoo/animals/zebra.h"
int main()
{
typedef zoo::animals::Zebra Zebra;
Zebra z;
Zebra::Count n = z.getLegCount();
// Not as zoo::animals::Count
// No using namespace zoo::animals required,
// we are using just one item from there, the Zebra.
// Definition of Zebra::Count may change, your usage remains robust.
return 0;
}
我的工作场所也有类似的情况。它的翻译可能有点愚蠢,但我想急着提出它。