返回类型上的类型限定符是否没有意义?

编程语言 2026-07-10

如果我有一个返回 const-限定类型的函数模板(例如,函数体很简单):

const auto f(auto) { return 1; }

并且我想获得该函数的一个具体实例的指针

const int(*x)(int) = f;
  • 只有在GCC中才会无警告地工作。
  • Clang与 EDG对此给出各自的警告:
warning: 'const' type qualifier on return type has no effect [-Wignored-qualifiers]
warning: type qualifier on return type is meaningless
  • MSVC完全拒绝它:
error C2440: 'initializing': cannot convert from 'const auto (__cdecl *)(_T0)' to 'const int (__cdecl *)(int)'

与此同时,MSVC接受不带 const-限定符的函数指针:

int(*y)(int) = f;

这也被所有其他实现拒绝。 在线演示

这里到底哪种行为才是正确的?

解决方案

MSVC是错的,其他实现是正确的。

const 在此情况下没有作用,但它仍然是函数模板签名的一部分。

MSVC在处理这个赋值时似乎忘记了那个无意义的 const 也是签名的一部分:

const auto f(auto) { return 1; }
int(*x)(int) = f;

因此,MSVC接受它,而其他实现应当拒绝。

MSVC也不一致。它似乎只有在函数模板具有推导返回类型时才拒绝赋值:

const auto f(int) { return 1; }  // ok (only deduced return type)
const int f(auto) { return 1; }  // ok (only function template)
const auto f(auto) { return 1; } // NOK (both)
//
const int(*x)(int) = f;

不过,它确实接受传统的模板参数:

template<class T>
const auto f(T) { return 1; }

const int(*x)(int) = f; // ok by all implementations
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章