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

标签 c++ templates gcc clang language-lawyer

[5.3.3/3] 所述(expr.sizeof,工作草案):

The sizeof operator can be applied to a pointer to a function, but shall not be applied directly to a function.

以下最小的工作示例可以正常编译:

void f() { }

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

我希望下面的那个也能工作:

template<typename T>
void f() { }

int main() {
    sizeof(&f<int>);
}

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

error: address of overloaded function with no contextual type information

我怀疑是GCC的bug(如果确定我会开工票)
我是对的还是我在这里遗漏了一些东西,而 GCC 确实是对的?


与此同时,我打开了 an issue到海湾合作委员会。

最佳答案

这是一个错误。以下代码编译正常:

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>);
}

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


我不会将其定性为错误。

将其定性为错误的论点如下 - 所有函数指针都具有相同的大小,那么为什么 sizeof 中的函数很重要呢?运营商?

我要打败那个论点。

首先,它是从错误的前提出发的。 C++ 标准只保证

converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value

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

接下来,即使我们接受了论证背后的前提和逻辑,那么我们也必须接受下面的程序也应该毫无问题地编译的说法:

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
}

继续以这种方式,我们认为,只要后续代码消除了编译歧义,就不应报告编译歧义。

关于c++ - sizeof 和函数模板 : sizeof(&f) vs sizeof(&f<int>),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39319745/

相关文章:

c++ - 在 C++ 中初始化指向结构的指针

C++如何读取文件并解析逗号分隔值

c++ - 使用 decltype 编写复制和 move 函数

c++ - 如何避免序列化器和容器序列化器之间的循环模板依赖?

c++ - 我如何创建一个接受 map 或 unordered_map 的函数?

c - 在按位补码的情况下,gcc在整数整数的约束下做什么?负左移计数是做什么的?

c++ - boost spirit x3 双解析器有限制

c++ - Boost.Test 和 fork

c - 使用另一个编译器更快的代码

c - 如何仅使用 C 编程语言用 GCC 编译 Allegro 5 程序