有没有什么情况下,typedef是绝对必要的?
考虑以下安全布尔成语的摘录:
typedef void (Testable::*bool_type)() const; operator bool_type() const;
是否可以声明转换函数没有typedef? 以下不编译:
operator (void (Testable::*)() const)() const;
啊,我只记得identity
元function。 这是可以写的
operator typename identity<void (Testable::*)() const>::type() const;
具有以下对identity
定义:
template <typename T> struct identity { typedef T type; };
你可能会认为identity
仍然使用typedef
,但是这个解决scheme对我来说是“好”的。
一种情况(与你的问题无关)需要typedef
是使用
va_arg()
macros。 引用C99标准(7.15.1.1):
键入* va_arg(va_list ap, type );
…
参数types应该是一个指定的types名称,以便指向具有指定types的对象的指针的types可以简单地通过后缀a *来获得
回答“是否有这样的情况,typedef是绝对必要的?” 从问题标题中,下面是需要typedef的一个例子:
f(unsigned char()); // compiler error! typedef unsigned char Byte; f(Byte()); // fine!
在这里查看结果: http : //ideone.com/JPUra
我的分析说,不使用typedef
是不可能的。 编译器看到(
作为第一个标记,并假设你是重载() operator
,它不应该有任何参数(参数将在下一组圆括号中)。把任何一组额外的括号也不会帮助 – 但会实际上混淆了编译器,因此造成了更多的错误。
大部分的STL代码都是在typedef
顶层,我们应该/必须使用它们!
看来,在你的情况下,语法要求使用typedef。 一个conversion-function-id的格式必须是operator conversion-type-id 。 conversion-type-id不能包含圆括号。 因此,在转换为函数指针types或指向成员函数types的指针时,必须使用typedef。
在C ++ 11中,你可以这样做(gcc 4.5.2):
operator decltype((void (Testable::*)() const)(0))() const ;
我不是说这很漂亮
一个typedef
不是一个macros你的第二个例子不等于第一个。 在第一种情况下,你的typedef
定义了一个仿函数,然后在仿函数types的转换操作符中使用该types。 在第二个操作符使用不好的语法,因为没有操作符指定,因为没有types。 我不知道如何写,但通常有一种方法。
除了在TMP中编写人类可读的代码,Typedefs并不是真正必要的,即使这样,它也取决于你是什么样的人。
由于我不能拿出替代语法,在某些情况下可能需要typedefs。 我只是想到另一个可能。 假设你有一个专门的模板,包含一个静态方法,返回types如下:
template <typename T> struct WhateverHandler { typedef T rType; static rType Whatever() { return rType(); } }; template <> struct WhateverHandler<std::string> { typedef std::string rType; static rType Whatever() { return rType(); } };
我认为在这种情况下,你也需要typedef来调用静态方法,不pipe是否有专门化,否则这个方法可能会混淆编译器,因为返回types会有所不同,但它不会是一个适当的重载。
template <typename T> struct WhateverUser { typename WhateverHandler<T>::rType DoWhatever() { return WhateverHandler<T>::template Whatever(); } };
我只是碰到这个问题,与铿锵声++:
foo.cpp:17:8: error: must use a typedef to declare a conversion to 'void (*(int))()'
还有一个涵盖了标识<T>function的C ++ 11 STL模板:
#include <type_traits> … struct foo { void bar( ) const { } operator std::common_type<void(foo::*)( )const>::type( ) { return &foo::bar; } };