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

标签 c++ language-lawyer overload-resolution template-argument-deduction argument-dependent-lookup

考虑以下示例:

#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 中声明的函数的定义.

关于c++ - 类模板中声明的友元函数的模板参数推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72900175/

相关文章:

c++ - 使用 COCOS2D-X 的文件 I/O

c++ - 可以在循环中使用相同的变量名吗?

c++ - 我丢失的 Edge 在哪里?

c++ - 在模板参数中,哪些规则允许编译器推断数组的项数?

c++ - 为什么仅仅因为有一个用户定义的析构函数,复制构造函数就不是微不足道的了?

c++ - 没有临时数组的列表初始化 - 在 GCC 中不起作用

delphi - 带有重载函数的编译器错误

C++ 转换运算符和重载决议

c++ - 一个 double 是否将方程中的每个 int 都提升为 double?

c++ - 为什么指针衰减优先于推导的模板?