c++ - 类模板中声明的友元函数的模板参数推导

考虑以下示例:

#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 找到声明 decl-2但是,这不是重载决策的可行候选函数(因为它未定义),因此编译器选择声明 decl-1 误解,并且与问题无关,请参阅@LanguageLawyer 的评论

我的问题是标准中的哪些规则允许编译器使用来自特化 spec-1 的模板参数来实例化包含 decl- 1.

搜索cppreference ,我发现似乎适用的唯一规则是指函数模板的重载解析,并引用:

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

decl-1 是否被视为用于重载决策的函数模板?编译器是否合成声明 template int Func<U, 42>(U)使用spec-1(大概是通过模板参数推导)?还是另有原因?

编辑: 我可能有的另一个误解是 spec-1 到底是什么,我目前的理解是它是类模板的显式特化声明S作为一个不完整的类型,如果可能请澄清这是否正确。

最佳答案

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.

这在 temp.explicit-12 中指定其中指出:

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.

(强调我的)

spec-1是一个显式实例化定义,结果将是类模板特化的实例化S<U, 42>


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

不,decl-1是普通(非模板)函数的定义。此外,这 decl-1只不过是在 decl-2 中声明的函数的定义.

https://stackoverflow.com/questions/72900175/

相关文章:

java - 是否可以向 OpenAPI 添加方法?

r - 按两个数字对列名称进行排序

r - 在 R 中使用 dplyr 包 Lag 函数时有没有办法省略 NA?

docker - 在 Golang 中使用 docker 将敏感数据作为参数传递

java - 关闭 AsynchronousSocketChannel 时连接重置错误

rust - 将未知类型的 PgRow 值转换为字符串

c# - 即使此 Func<> 变量为空,是什么导致内存分配?

swiftui - 带有条件绑定(bind)的 SwiftUI 中的错误必须具有可选类型,而不是字符

xaml - 删除开关中的文本

ios - SwiftUI:有条件地隐藏 View 而不重新创建它