与列表初始化语法的自动赋值混淆

Confusion with auto assignment with list initialization syntax

本文关键字:赋值 列表 初始化 语法      更新时间:2023-10-16

我现在才能够在我的工作中第一次使用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};
                  ^

我觉得我错过了一些明显的东西。我哪里做错了?

当您使用函数符号进行类型转换时,类型名必须是简单类型说明符类型说明符 (§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};

T(x)T{x}语法不允许对T使用任意类型。允许它在某些情况下会使语法变得相当复杂。如果真的想在这里使用auto,则需要将该类型换行,如下所示:

template <typename T> using id = T;
auto f = id<foo const*>{nullptr};

但我个人认为它在这里没有什么用。

更具体地说,c++语法将语法结构定义为 <>之前<我>后缀表达式:...simple-type-specifier (expression-listopt)...<我> simple-type-specifier <我> braced-init-list ...<我> simple-type-specifier ::: <子>选择<我> nested-name-specifier <子>选择<我>类型名称::optnested-name-specifier template simple-template-id字符char16_tchar32_twchar_t保龄球短int长签署无符号浮动双无效汽车<我> decltype-specifier <我>类型名称:<我>类名称<我> enum-name <我>类型名<我> simple-template-id 之前

允许任意类型的语法是type-id规则的一部分,它不是simple-type-specifier的选项之一,但却是simple-template-id中的template-argument规则的可能性之一,这就是为什么模板别名是一种有效的解决方案。