4

我有一些对类型和初始值进行操作的宏。我需要将初始值转换vInivType(vIni总是可转换为vType,有时它具有相同的类型)。vIni也可能为空,在这种情况下应该vType未初始化或默认初始化。结果被传递给模板化函数。

简而言之,

template<typename T> void foo(const T& o);

foo(vType(vIni));
foo(vType());

必须编译。

我已经发现foo(unsigned int())或者foo(int*())不会编译,但它可以使用 typedef 来解决。

还有哪些其他情况(除了带有空格和指针的内置类型)会失败?

4

1 回答 1

5

简短(稍微过度简化)的答案是,“除了简单类型说明符之外的任何东西都会失败”。

5.2.3/1 说:

一个简单类型说明符(7.1.6.2) 或类型名称说明(14.6) 后跟一个带括号的表达式列表构造一个给定表达式列表的指定类型的值。

简单类型说明符可以是类型的单字名称(可选地加上范围的一些内容::,和/或本身不需要是简单类型说明符的模板参数)或decltype表达式。7.1.6.2 列出了这些可能性。

unsigned int并且int*不是简单类型说明符。任何复合类型说明符都会失败,因此 cv 限定、数组类型、函数类型、指针类型(包括指向函数的指针和指向成员的指针)都需要 typedef。

还排除了多字类型标识符,如unsigned char, long double。对于您的第一个示例,unsigned将代替unsigned int.

typename-specifier是一个以 开头的类型,typename在模板中用于断言从属名称确实是一种类型,而不是数据成员或成员函数。

最后,当然,一旦你超越了这个限制,类型实际上必须是可构造的或可从expression-list转换的。因此,例如,您不能使用此语法或任何其他语法创建临时函数类型。

于 2012-05-10T12:21:59.203 回答