考虑来自安全布尔值习惯用法的以下摘录:
typedef void (Testable::*bool_type)() const;
operator bool_type() const;
能否在不使用typedef的情况下声明转换函数?以下代码无法编译:
operator (void (Testable::*)() const)() const;
考虑来自安全布尔值习惯用法的以下摘录:
typedef void (Testable::*bool_type)() const;
operator bool_type() const;
能否在不使用typedef的情况下声明转换函数?以下代码无法编译:
operator (void (Testable::*)() const)() const;
identity
元函数。可以这样编写:operator typename identity<void (Testable::*)() const>::type() const;
在以下 identity
的定义中:
template <typename T>
struct identity
{
typedef T type;
};
identity
仍然使用了typedef
,但对我来说,这个解决方案已经足够"好"了。identity
是一个不错的方法,可以避免解析问题。 - David Rodríguez - dribeasidentity
不是标准 C++0x 的一部分。在这种情况下,我们可以使用 std::decay
... - fredoverflow一个例子(与你的问题无关)需要使用typedef
的情况是使用va_arg()
宏时。引用C99标准(7.15.1.1):
type* va_arg(va_list ap, type);
...
参数type应该是指定类型名称,可以通过在type后面加上*来获得指向具有指定类型的对象的指针的类型。
p->~unsigned char()
(对于那些不知道伪析构函数是什么或为什么需要在那里使用typedef的人)。 - MSalters回答问题标题中的“typedef是否绝对必要?”这个问题,这里有一个需要使用typedef的例子:
f(unsigned char()); // compiler error!
typedef unsigned char Byte;
f(Byte()); // fine!
f(identity<unsigned char>::type())
怎么样? ;) - fredoverflowtype
是一个 typedef。 :P - user802003operator decltype((void (Testable::*)() const)(0))() const ;
我并不是说这很漂亮...
decltype(&Testable :: foo)
吗?其中foo
是具有适当签名的成员方法? - David Rodríguez - dribeastypedef
,则不可能实现。编译器将看到 (
作为第一个标记,并假定您正在重载 () 运算符
,该运算符不应具有任何参数(下一组括号中会出现参数)。添加任何一组额外的括号也无济于事,实际上会让编译器混淆,从而导致更多错误。typedef
定义,我们应该/必须使用它们!在您的情况下,语法要求使用 typedef。一个conversion-function-id必须是operatorconversion-type-id的形式。 conversion-type-id不能包含括号。因此,当转换为指向函数类型或指向成员函数类型时,必须使用typedef。
template <int T> class C { } ; class S { operator C<(99)>*() { return 0 ; } } ;
- TonyKtypedef
不是宏,你的第二个例子与第一个不等价。在第一个情况下,你的typedef
定义了一个函数对象,然后在函数对象类型的转换运算符中使用该类型。在第二种情况下,操作符使用了错误的语法,因为没有指定操作符,因为没有类型。我不确定如何编写它,但通常有一种方法。
除了在TMP中使代码易读之外,typedef
并不是真正必要的,甚至这也取决于你是什么样的人类。
由于我想不出替代语法,也许在某些情况下typedef
是必要的。我刚想到另一个可能性。假设你有一个包含具有以下返回类型的静态方法的特化模板:
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,以便无论特化如何调用静态方法,否则方法可能会让编译器混淆,因为返回类型将不同,但它不是一个合适的重载。
template <typename T>
struct WhateverUser
{
typename WhateverHandler<T>::rType DoWhatever()
{
return WhateverHandler<T>::template Whatever();
}
};
我刚刚遇到了这个问题,使用clang++:
foo.cpp:17:8: error: must use a typedef to declare a conversion to 'void (*(int))()'
还有一个 C++11 STL 模板可以覆盖 identity<T> 功能:
#include <type_traits>
…
struct foo {
void bar( ) const { }
operator std::common_type<void(foo::*)( )const>::type( ) { return &foo::bar; }
};
optional<T>
类模板),它似乎很有用。 - fredoverflowtypedef
有助于产生更易读的代码/错误。 - Matthieu M.