Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1033787
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T14:17:05+00:00 2026-05-16T14:17:05+00:00

Consider this code: template <int N> struct X { friend void f(X *) {}

  • 0

Consider this code:

template <int N>
struct X
{
 friend void f(X *) {}
};

int main()
{
 f((X<0> *)0); // Error?
}

compilers seem to heavily disagree. (MSVC08/10 says no, GCC<4.5 says yes, but 4.5 says no, sun 5.1 says yes, intel 11.1 says yes too but comeau says no (both are EDG)).

According to “C++ Templates – The complete guide”:

… it is assumed that a call
involving a lookup for friends in
associated classes actually causes the
class to be instantiated … Although
this was clearly intended by those who
wrote the C++ standard, it is not
clearly spelled out in the standard.

I couldn’t find the relevant section in the standard. Any reference?

Consider this variation:

template <int N>
struct X
{
 template <int M>
 friend void f(X<M> *) {}
};

template <>
struct X<0>
{
};

int main()
{
 X<1>();
 f((X<0> *)0); // Error?
}

The key issue here is wether the viable function injected by X<1> should be visible during ADL for X<0>? Are they associated? All compilers mentioned above accept this code, except for Comeau which only accepts it in relaxed mode. Not sure what the standard has to say about this either.

What’s your take on that?

  • 1 1 Answer
  • 1 View
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T14:17:06+00:00Added an answer on May 16, 2026 at 2:17 pm

    The Standard says at 14.7.1/4

    A class template specialization is implicitly instantiated if the class type is used in a context that requires a completely-defined object type or if the completeness of the class type affects the semantics of the program; in particular, if an expression whose type is a class template specialization is involved in overload resolution, pointer conversion, pointer to member conversion, the class template specialization is implicitly instantiated (3.2);

    Note that Vandervoorde made an issue report here, and the committee found

    The standard already specifies that this creates a point of instantiation.

    For your second case – you need to consider the associated classes and namespaces of the argument f(X<0>*). These are, since this is a pointer to a class template specialization (note that “template-id” below is not quite correct – C++0x corrected that to use the correct term) and also a pointer to a class (this confusing split was also corrected in C++0x – it lists these two cases in one bullet point).

    • If T is a template-id, its associated namespaces and classes are the namespace in which the template is
      defined; [… lots of noise …]

    • If T is a class type (including unions), its associated classes are: the class itself; the class of which it is a member, if any; and its direct and indirect base classes. Its associated namespaces are the namespaces in which its associated classes are defined.

    So to summary, we have as associated classes are X<0> and the associated namespaces are the global namespace. Now the friend functions that are visible are

    • Any namespace-scope friend functions declared in associated classes are visible within their respective namespaces even if they are not visible during an ordinary lookup

    There is no friend function declared in X<0> so the friend function declaration is not visible when looking into the global namespace. Note that X<0> is an entirely different class-type than X<1>. The implicit instantiation of X<1> you do there has no effect on this call – it just adds a non-visible name into the global namespace that refers to a friend function of class X<1>.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider this code: #include <iostream> template<class C> struct time { }; int main() {
consider this simple and pointless code. #include <iostream> struct A { template<int N> void
Please consider this code: template<typename T> char (&f(T[1]))[1]; template<typename T> char (&f(...))[2]; int main()
Consider this code: int main() { int e; prn(e); return 0; } void prn(double
Consider this code: void res(int a,int n) { printf(%d %d, ,a,n); } void main(void)
Consider the following code: struct Foo { mutable int m; template<int Foo::* member> void
Consider this code: if(initscr() == NULL) ERROR(Cannot start ncurses mode.\n); keypad(stdscr, TRUE); cbreak(); int
Consider the following code template<typename T, int N> struct A { typedef T value_type;
Please consider this code: #include <iostream> template<typename T> void f(T x) { std::cout <<
Consider the following code: template <int dim> struct vec { vec normalize(); }; template

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.