我现在能够在我的工作中第一次使用C ++ 11,而且我可以随时学习。我已阅读GotW #94,并且在宣布局部变量而不是明确说明类型时,我尝试采用他的建议来使用auto
。
鉴于此,我有以下代码:
class foo
{
};
int main()
{
auto f = foo const*{nullptr};
}
我在main中的作业无法编译并失败:
main.cpp: In function 'int main()':
main.cpp:13:18: error: expected primary-expression before 'const'
auto f = foo const*{nullptr};
^
我觉得我错过了一些明显的东西。我在这里做错了什么?
(我的样本是on coliru)。
答案 0 :(得分:4)
使用函数表示法进行类型转换时,类型名称必须是简单类型说明符或 typename-specifier (§5.2.3 [expr.type.conv] ),基本上是指由单个单词组成的类型名称。
unsigned int a = unsigned int(42);
也失败了,并且没有涉及类型推断或列表初始化。
在我看来,在您的示例中使用auto
相当于混淆。只需使用
foo const* f{nullptr};
如果必须使用auto
,请创建别名
using foo_const_p = foo const*;
auto f = foo_const_p{nullptr};
答案 1 :(得分:1)
T(x)
和T{x}
语法不允许将任意类型用于T
。在某些情况下允许它会使语法相当复杂。如果确实想在这里使用auto
,您需要包装类型,如下所示:
template <typename T> using id = T;
auto f = id<foo const*>{nullptr};
但就个人而言,我并不认为它在这里很有用。
更具体地说,C ++语法将语法结构定义为
postfix-expression: ... simple-type-specifier ( expression-listopt ) ... simple-type-specifier braced-init-list ... simple-type-specifier: ::opt nested-name-specifieropt type-name ::opt nested-name-specifier template simple-template-id char char16_t char32_t wchar_t bool short int long signed unsigned float double void auto decltype-specifier type-name: class-name enum-name typedef-name simple-template-id
允许任意类型的语法是type-id
规则的一部分,simple-type-specifier
规则不是template-argument
的选项之一,而是simple-template-id
规则中{{1}}规则的可能性之一{{1}},这就是模板别名是有效解决方法的原因。