最近我在代码中遇到了以下构造:
typedef sometype sometype;
Run Code Online (Sandbox Code Playgroud)
请注意"sometype"代表完全相同的类型,没有任何添加,如"struct"等.
我想知道它有什么用处?
UPD:这仅适用于用户定义的类型.
UPD2:实际代码在模板上下文中,如下所示:
template <class T>
struct E
{
typedef T T;
...
}
Run Code Online (Sandbox Code Playgroud)
如何使模板参数对外部实体可见?
template <class Foo>
struct Bar
{
typedef Foo Foo;
};
int main()
{
Bar<int>::Foo foo = 4;
}
Run Code Online (Sandbox Code Playgroud)
注意:这在标准C++中实际上是不允许的,但是特定于MSVC.看评论.
鉴于您有关模板的其他信息,我们现在可以回答.
用例是指您想要专注于模板的类型.一个典型的例子如下:
template <typename T>
struct nonconst {
typedef T t;
};
template <typename T>
struct nonconst<T const> {
typedef T t;
};
Run Code Online (Sandbox Code Playgroud)
这有效地允许您const从任何类型中删除限定符:
nonconst<int>::t x;
nonconst<int const>::t y;
assert(typeid(x) == typeid(int));
assert(typeid(y) == typeid(int));
Run Code Online (Sandbox Code Playgroud)
有许多类似的用例,例如从类型中添加(或删除)指针限定符,为某些类型提供默认值和特化等.
但是,请注意类型名称的不同外壳!等同类型[我的立场更正:§7.1.3.2]此外,事实命名标准(通过在Boost库中使用来巩固)是调用类型名称别名typedef T T是非法的C++.type,例如:
typedef T type;
Run Code Online (Sandbox Code Playgroud)
在C++中,您可以将typedef放在命名空间或类中,然后相对于该命名空间或类引用它,如果真实类型将来可能会更改,这可能很有用.
例如
class IntHolder
{
public:
typedef int int;
IntHolder::int i;
};
...
IntHolder foo;
IntHolder::int i = foo.i;
Run Code Online (Sandbox Code Playgroud)
(注意:我没有检查过这是非常正确的语法 - 但希望你能得到这个想法)
如果在某个未来的某个时刻你真的想要保留long在IntHolder你身上,只需要更改IntHolder代码.
现在,通常你用不同的名字命名,但也许你可以这样做?
我有一个理论.这可能是一些重构的结果.例如,模板化类型不是模板化的.
typedef SomeCleverTemplate<Rocket> SuperThing;
Run Code Online (Sandbox Code Playgroud)
然后他们删除了模板,因为代码中没有其他用法,为了安全起见,他们将每个替换SomeCleverTemplate<Rocket>为SuperThing.
typedef SuperThing SuperThing;
Run Code Online (Sandbox Code Playgroud)
它在真实环境中是否有意义?