c++ - 使用 C++11 auto 关键字声明两个(或更多)变量

标签 c++ c++11 templates auto

我有这样的代码:

template<class ListItem>
static void printList(QList<ListItem>* list)
{
    for (auto i = list->size() - 1, j = -1; i >= 0; --i) {
        std::cout << i << ", " << j << ": " << list->at(i) << std::endl;
    }
}

当我用 g++ 6.2.1 编译它时,我得到以下编译器输出:

test.cpp: In function ‘void printList(QList<T>*)’:
test.cpp:10:7: error: inconsistent deduction for ‘auto’: ‘auto’ and then ‘int’
  for (auto i = list->size() - 1, j = -1; i >= 0; --i) {
       ^~~~

如果变量具有不同的类型,例如 auto i = 0.0, j = 0;,我会理解,但在这种情况下,list 是指向 QList 的指针,它的 size() 方法返回 int, -1 本身也应该是 int。错误信息也有点奇怪。

变量 ij 仅在此循环中需要,我想将它们声明为循环参数。键入 int 而不是 auto 并不难,但我想知道:auto 是否不应该用于一次性声明多个变量,或者我是这里遗漏了一些东西,这确实是错误的代码,或者是编译器的错误?

附:看起来使用模板函数是这里的关键部分,将循环从模板中分解出来不会产生错误。那么,更像是编译器中的一个错误?

Live demo - minimal code

最佳答案

这是 GCC 中的一个错误。

根据[dcl.spec.auto]/1:

The auto and decltype(auto) type-specifiers are used to designate a placeholder type that will be replaced later by deduction from an initializer. [...]

模板参数推导的规则永远不会将类型推导出为 auto。这种情况下推导的目的其实就是替换 auto 为推导的类型。

在例子中,list有一个依赖类型(它依赖于模板参数ListItem),所以表达式list->size() - 1 也有一个依赖类型,这使得 i 的类型也依赖,这意味着它只会在函数模板 printList 的实例化时被解析。只有这样才能检查与该声明相关的其他语义约束。

根据[temp.res]/8:

Knowing which names are type names allows the syntax of every template to be checked. The program is ill-formed, no diagnostic required, if:

[... long list of cases of which none applies here ...]

Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated. [ Note: If a template is instantiated, errors will be diagnosed according to the other rules in this Standard. Exactly when these errors are diagnosed is a quality of implementation issue. — end note ]

(强调我的)

GCC 在分析模板 printList 的定义时发出该错误是错误的,因为可以生成明显有效的模板特化。事实上,如果 QList 没有任何 size() 返回 int 以外的特化,则 i 的声明j 将在 printList 的所有实例中有效。


所有报价均来自N4606 ,(几乎)当前的工作草案,但上述引用的相关部分自 C++14 以来没有改变。


更新:Confirmed as a regression在 GCC 6/7 中。感谢 T.C.用于错误报告。

更新:原始错误 (78693) 已在即将发布的 6.4 和 7.0 版本中修复。它还发现了 GCC 处理此类构造的方式的一些其他问题,导致另外两个错误报告:7900979013 .

关于c++ - 使用 C++11 auto 关键字声明两个(或更多)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40841777/

相关文章:

c++ - 为什么此代码工作/失败取决于范围关闭创建于?

c++ - 如何使用 QTimeLine 为两个值设置动画

c++在容器类中调用私有(private)函数

c++ - 将 QQmlListProperty 作为参数从 QML 传递到 C++

c++ - 返回 vector<pair<string,string>> 会导致 gcc 编译代码 (curlcpp) 崩溃

c++ - 复制省略 : move constructor not called when using ternary expression in return statement?

c++ - sizeof childclass 如何在父模板类中使用子类作为模板参数?

c++ - "opencv2 computer vision application programming cookbook"书中代码的QT配置

c++11 decltype 返回引用类型

c++ - 如何删除析构函数中的void指针?