sizeof 和函数模板:sizeof(&f) vs sizeof(&f<int>)

sizeof and function template: sizeof(&f) vs sizeof(&f<int>)

本文关键字:sizeof int gt vs 函数模板 lt      更新时间:2023-10-16

如[5.3.3/3](expr。(工作稿):

sizeof操作符可以应用于指向函数的指针,但不能直接应用于函数。

以下最小的工作示例编译得很好:

void f() { }
int main() {
    sizeof(&f);
}

我希望下面这个也可以:

template<typename T>
void f() { }
int main() {
    sizeof(&f<int>);
}

无论如何,即使它使用clang (v3.8)编译,它也不使用GCC (v6.1)。
错误是:

错误:没有上下文类型信息的重载函数地址

我怀疑这是GCC的一个bug(如果确认,我会打开一个票证)。
我是对的,还是我遗漏了什么,GCC确实是对的?


同时,我打开了一个issue给GCC.

这是一个bug。下面的代码可以正常编译:

template<typename T>
void f() { }
int main() {
    auto fptr = &f<int>;
    return sizeof(fptr);
}

请注意,一开始我没有认真阅读问题。在我的印象中,函数f<int>确实是重载的,例如如下:
template<typename T>
void f() { }
template<typename T>
void f(T) { }
int main() {
    sizeof(&f<int>);
}

在这样的阅读问题下,我准备了以下答案,我仍然想与社区分享:


我不认为这是一个bug。

将其定性为错误的参数如下-所有函数指针具有相同的大小,那么为什么在sizeof操作符中表示哪个函数很重要?

我要推翻那个论点。

首先,它从错误的前提开始。c++标准只保证

将"指针指向T1"类型的右值转换为"指针指向"类型T2"(其中T1T2是函数类型)并返回到其原始类型产生原始指针值

并不一定意味着指向不同类型函数的指针的大小是相同的。然而,我承认在实践中这是正确的。

接下来,即使我们接受实参背后的前提和逻辑,那么我们也必须接受以下程序也应该编译没有任何问题的声明:

template<typename T>
void f() { }
template<typename T>
void f(T) { }
int main() {
    auto fptr = &f<int>;
    return sizeof(fptr);
    // fptr is not used anywhere else, so the compiler must not
    // whine about the ambiguity on its declaration line
}

继续这种方式,我们会认为编译歧义不应该被报告,只要它们被后续代码消除。