为 return 类型的专用模板函数使用 auto 时出错

Error using auto for return type of specialised template function

考虑以下代码片段(从更复杂的代码简化而来):

#include <typeinfo>
#include <iostream>

struct A{
    template<int S>
    void print(){ std::cout << S << std::endl; }
};

struct B{};

template <class T>
A foo(int);

template<>
A foo<B>(int){ return A{}; }

template<class T>
int bar(int){
  auto res = foo<T>(0);
  std::cout << typeid(res).name() << std::endl;
  res.print<5>();       // This line gives an error
  return 0;
}

int main() {
  bar<B>(0);
  return 0;
}

Live example

如果我尝试编译它(使用 gcc 或 clang),它会导致以下错误:

main.cpp:21:16: error: expected primary-expression before ')' token
   21 |   res.print<5>();

我必须:

为了编译这段代码。

我不太擅长解释标准语言,但据我所知,调用 模板成员函数时需要函数调用中的 template 关键字 在类型 明确依赖于模板参数 的对象上(例如参见 [​​=24=])。

在这种情况下,我没想到需要关键字 template,因为 res 应该是 A 类型的对象,它不明确依赖于模板参数(即使它是模板函数调用的结果)。

有人可以帮助我了解我错在哪里,以及什么时候真正需要 template 关键字吗?

提前致谢,如果这是一个重复的问题,我深表歉意,但我找不到类似问题的具体内容。

就编译器所知,在程序的某处它还没有看到存在 foo 的特殊化 T returns 除了 A.所以它不能假设 res 总是 A。因此,res的类型实际上确实依赖于模板参数T,那么res.print毕竟是一个依赖名称。

然后需要

template 关键字让编译器知道 print 之后的尖括号将被解析为构成 template-id 一部分的尖括号,而不是小于运算符。