简体   繁体   中英

How does that syntax for defining a full function template specialization a friend of a class?

I saw the following example at cppreference (" Template friend operators" section), simplified

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>{});
}

Here either (1) or (2) work equally well. I understand that in (1) compiler says that one specific instantiation of bar (namely, bar<T> with such-and-such parameters) is a friend of Foo<T> , but I do not understand what happens in (2) .

What type parameters does compiler use for bar in (2) ? How does that work in general? How is that syntax called, is it defined somewhere in the Standard?

See 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.

The names bar<T> and bar<> are both template-id s, so if you use either one, then it refers to a specialization of the function template ::bar . As specified in [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; ...

Thus, the meaning of bar<> in the friend declaration is that template argument deduction shall be done to determine which specialization of bar is being referred to. Of course, the deduced specialization is the one that takes an argument of the type Foo<T> . So the two declarations with bar<> and bar<T> would have the same meaning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM