扣除在类模板中声明的朋友函数的模板参数

发布于 2025-02-13 23:06:59 字数 1474 浏览 0 评论 0原文

考虑以下示例:

#include <iostream>

template <class T, int V>
struct S
{
    friend int Func(T) // decl-1
    {
        return V;
    }
};

struct U
{
    friend int Func(U); // decl-2
};

template struct S<U, 42>; // spec-1

int main()
{
    std::cout << Func(U{}) << std::endl; // Compiles and prints 42
}

我的理解是func(u {})导致函数func 的不合格的名称查找,并且通过ADL查找声明 ext -2 但是,这不是过载分辨率的可行候选功能(由于未定义),因此编译器选择声明 exl> ext-1 。。 误解和与问题无关,请参阅@languagelawyer的评论

我的问题是标准中的哪个规则允许编译器使用“专业化”模板参数 类模板。

spec-1 实例化包含 dect-1 的 /cpp“ rel =“ nofollow noreferrer”> cppReference ,我发现似乎应用的唯一规则是指函数模板的过载分辨率,并引用:

对于函数模板,执行模板参数扣除和检查任何明确的模板参数以查找在这种情况下可以使用的模板参数值(如果有):

  • 如果两者都成功,则使用模板参数来综合相应函数模板专业的声明,这些声明被添加到候选集合中,并且该专业的处理方式就像非网板函数一样处理规则;
  • 如果参数扣除失败或合成函数模板专业化将是不形式的,则不会将此类功能添加到候选人集中。
来源: https://en.cppreference.com/w/cpp /语言/Overload_resolution#详细信息

IS ext-1 考虑了一个函数模板,以实现超载的目的 解决?编译器是否合成声明模板int func&lt; u,42&gt;(u)使用 spec-1 (通过模板参数扣除,大概是)?还是这里有其他事情在这里?

编辑:我可能拥有的另一种误解是 spec-1 ,我目前的理解是,这是对类模板的明确专业化的声明S作为不完整的类型,如果可能的话,请澄清一下。

Consider the following example:

#include <iostream>

template <class T, int V>
struct S
{
    friend int Func(T) // decl-1
    {
        return V;
    }
};

struct U
{
    friend int Func(U); // decl-2
};

template struct S<U, 42>; // spec-1

int main()
{
    std::cout << Func(U{}) << std::endl; // Compiles and prints 42
}

My understanding is that the expression Func(U{}) causes an unqualified name lookup of the function Func, and through ADL finds declaration decl-2. However, this is not a viable candidate function for overload resolution (since it is not defined), and thus the compiler selects declaration decl-1. Misunderstanding, and irrelevant to the question, see comment from @LanguageLawyer

My question is what rule(s) in the standard allow the compiler to use the template parameters from the specialization spec-1 to instantiate the class template that contains decl-1.

Searching through cppreference, the only rule I found that seems to apply refers to overload resolution of function templates, and to cite:

For function templates, template argument deduction and checking of any explicit template arguments are performed to find the template argument values (if any) that can be used in this case:

  • if both succeeds, the template arguments are used to synthesize declarations of the corresponding function template specializations, which are added to the candidate set, and such specializations are treated just like non-template functions except where specified otherwise in the tie-breaker rules;
  • if argument deduction fails or the synthesized function template specialization would be ill-formed, no such function is added to the candidate set.
Source: https://en.cppreference.com/w/cpp/language/overload_resolution#Details

Is decl-1 considered a function template for the purposes of overload resolution? Does the compiler synthesize a declaration template int Func<U, 42>(U) using spec-1 (through template argument deduction, presumably)? Or is something else at play here?

EDIT: An additional misconception that I may have is what exactly is spec-1, my current understanding is that it is the declaration of an explicit specialization of class template S as an incomplete type, if possible please clarify if this is correct.

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

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

发布评论

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

评论(2

夏日浅笑〃 2025-02-20 23:06:59

标准中的哪个规则允许编译器使用“专业规格1”的模板参数来实例化包含dect-1的类模板。

这是在哪个指出:

一个明确的实例化定义,该定义名称类模板专业化明确实例化了类模板专业,并且是仅在实例上定义的那些成员的明确实例化定义。

>

>

(强调我的)

并且由于spec-1 显式实例定义,结果将是类模板专业化的实例化s&lt; u,42&gt; < /代码>


出于超负荷分辨率的目的,dect-1是否被视为函数模板?

否,ext-1是普通(非网板)函数的定义。 Moroever,此ext-1不过是在exling-2中声明的函数的定义。

what rule(s) in the standard allow the compiler to use the template parameters from the specialization spec-1 to instantiate the class template that contains decl-1.

This is specified in temp.explicit-12 which states that:

An explicit instantiation definition that names a class template specialization explicitly instantiates the class template specialization and is an explicit instantiation definition of only those members that have been defined at the point of instantiation.

(emphasis mine)

And since spec-1 is an explicit instantiation definition, the result will be the instantiation of the class template specialization S<U, 42>


Is decl-1 considered a function template for the purposes of overload resolution?

No, decl-1 is a definition for an ordinary(non-template) function. Moroever, this decl-1 is nothing but the definition for the function declared in decl-2.

蘑菇王子 2025-02-20 23:06:59

我可能拥有的另一种误解是Spec-1,我当前的理解是,这是将类模板S的明确专业化为不完整的类型,如果可能的话,请澄清一下,如果这是正确的。<<<<<<<<<<< /p>

这是不正确的。

template struct S<U, 42>; // spec-1

根本不是专业,而是

它只是告诉编译器使用参数发射s的相同实例化t = uv = 42,如果您引用了,则会发出。在任何其他情况下,s&lt; u,24&gt;

作为不完整类型的专业化看起来像

template <> struct S<U, 42>;

An additional misconception that I may have is what exactly is spec-1, my current understanding is that it is the declaration of an explicit specialization of class template S as an incomplete type, if possible please clarify if this is correct.

This is not correct.

template struct S<U, 42>; // spec-1

Is not a specialization at all, but an explicit instantiation.

It just tells the compiler to emit the same instantiation of S with parameters T=U and V=42 that would have been emitted if you referred to S<U, 24> in any other context.

A specialization as an incomplete type looks like

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