超载函数模板仅在C+&#x2B中仅在返回类型上有所不同。

发布于 2025-02-13 05:49:29 字数 661 浏览 1 评论 0 原文

众所周知,仅在返回类型上有所不同的普通函数不能在C ++中超载。

但是,此限制不适合过载函数模板,例如:

int f(auto) { return 1; }
auto f(auto) { return 2; }

所有编译器都接受它,演示:

为什么该语言为此提供了这样的例外模板?

如果重载函数的返回类型有所不同,则可以使用cast到预期功能类型选择其中一个功能。令人惊讶的是,Clang允许人们解决歧义,即使返回类型实际上相同,例如:

((int(*)(int))f)(3);

选择

int f(auto) { return 1; }

演示:“ noreferrer”> https://gcc.godbolt.org/z/snfvbq1me

是错误的 这里?

It is well known that ordinary functions that differ only in their return type cannot be overloaded in C++.

But this limitation does not hold for overloaded function templates, for example:

int f(auto) { return 1; }
auto f(auto) { return 2; }

All compilers accept it, demo: https://gcc.godbolt.org/z/qj73Mzehd

Why does the language make such exception for the templates?

If the return type of the overloaded functions differ, then it will be possible to select one of the functions using the cast to expected function type. Surprisingly, Clang allows one to resolve the ambiguity even if the return type is actually the same, for example:

((int(*)(int))f)(3);

selects

int f(auto) { return 1; }

Demo: https://gcc.godbolt.org/z/snfvbq1ME

Is Clang wrong here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伊面 2025-02-20 05:49:30

为什么该语言对模板有这样的例外?

你的意思是吗?

签名 [defns.signature.templ]

⟨函数模板⟩名称,参数型列表,封闭命名空间(如果有),返回类型,模板头和尾随需要c-lause(如果有)

是的,返回类型在那里。这总是使诸如

template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type foo(T&);

template<typename T>
typename std::enable_if<!std::is_integral<T>::value>::type foo(T&);

Sfinae之类的可能的原因是为什么签名中包含返回类型的原因。在返回类型中可能发生替换故障,因此这是签名比较的一部分。您仍然可能会产生两个相互矛盾的专业,以使其过载(在一般情况下,不是在示例中),但是模板会有所不同。

Why does the language make such exception for the templates?

You mean this?

signature [defns.signature.templ]

⟨function template⟩ name, parameter-type-list, enclosing namespace (if any), return type, template-head, and trailing requires-clause (if any)

Yes, the return type is there. It's what always made possible things like

template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type foo(T&);

template<typename T>
typename std::enable_if<!std::is_integral<T>::value>::type foo(T&);

SFINAE is why the return type is included in the signature. Substitution failure is possible in the return type, so it's part of signature comparison. You can still potentially generate two conflicting specializations to overload on (in the general case, not in the example), but the templates would be different.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文