用于定义完整功能模板的语法如何专门化 class 的朋友?
How does that syntax for defining a full function template specialization a friend of a class?
我在 cppreference(“模板友元运算符”部分)看到了以下示例,已简化
template<typename> struct Foo;
template<typename T> void bar(Foo<T>) {}
template<typename T>
struct Foo {
// friend void bar<T>(Foo f); // (1)
friend void bar<>(Foo f); // (2)
};
int main() {
bar(Foo<int>{});
}
此处 (1)
或 (2)
都同样有效。我知道在 (1)
中,编译器说 bar
的一个特定实例(即带有某某参数的 bar<T>
)是 Foo<T>
的朋友,但我知道不明白 (2)
.
中发生了什么
(2)
中的 bar
编译器使用什么类型的参数?这通常是如何工作的?该语法是如何调用的,它是否在标准中的某处定义?
参见 C++17 [temp.friend]/1:
A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class. For a friend function declaration that is not a template declaration:
- if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise,
- if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,
- if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template (17.8.2.6), otherwise,
- the name shall be an unqualified-id that declares (or redeclares) a non-template function.
名字bar<T>
和bar<>
都是template-ids,所以如果你使用任何一个,那么它指的是函数模板 ::bar
。如 [temp.arg.explicit] 中指定:
Template arguments can be specified when referring to a function template specialization by qualifying the function template name with the list of template-arguments ... A template argument list may be specified when referring to a specialization of a function template ... in a friend declaration. Trailing template arguments that can be deduced (17.8.2) or obtained from default template-arguments may be omitted from the list of explicit template-arguments. ... If all of the template arguments can be deduced, they may all be omitted; ...
因此,friend 声明中bar<>
的含义是,应进行模板参数推导以确定引用bar
的哪个特化。当然,推导的特化是采用 Foo<T>
类型参数的特化。所以带有 bar<>
和 bar<T>
的两个声明具有相同的含义。
我在 cppreference(“模板友元运算符”部分)看到了以下示例,已简化
template<typename> struct Foo;
template<typename T> void bar(Foo<T>) {}
template<typename T>
struct Foo {
// friend void bar<T>(Foo f); // (1)
friend void bar<>(Foo f); // (2)
};
int main() {
bar(Foo<int>{});
}
此处 (1)
或 (2)
都同样有效。我知道在 (1)
中,编译器说 bar
的一个特定实例(即带有某某参数的 bar<T>
)是 Foo<T>
的朋友,但我知道不明白 (2)
.
(2)
中的 bar
编译器使用什么类型的参数?这通常是如何工作的?该语法是如何调用的,它是否在标准中的某处定义?
参见 C++17 [temp.friend]/1:
A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class. For a friend function declaration that is not a template declaration:
- if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise,
- if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,
- if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template (17.8.2.6), otherwise,
- the name shall be an unqualified-id that declares (or redeclares) a non-template function.
名字bar<T>
和bar<>
都是template-ids,所以如果你使用任何一个,那么它指的是函数模板 ::bar
。如 [temp.arg.explicit] 中指定:
Template arguments can be specified when referring to a function template specialization by qualifying the function template name with the list of template-arguments ... A template argument list may be specified when referring to a specialization of a function template ... in a friend declaration. Trailing template arguments that can be deduced (17.8.2) or obtained from default template-arguments may be omitted from the list of explicit template-arguments. ... If all of the template arguments can be deduced, they may all be omitted; ...
因此,friend 声明中bar<>
的含义是,应进行模板参数推导以确定引用bar
的哪个特化。当然,推导的特化是采用 Foo<T>
类型参数的特化。所以带有 bar<>
和 bar<T>
的两个声明具有相同的含义。