1
template<typename T> class FooBar {};

template<typename T> class Bar {
    friend class FooBar<T>;
};

template<typename T> class Bar2 {
    template friend class FooBar<T>;
};

What is the difference between class Bar and Bar2?

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
q0987
  • 34,938
  • 69
  • 242
  • 387

2 Answers2

8

The second one you have is invalid syntax, according to my compiler. If you change them to:

template<typename T> class FooBar {};

template<typename T> class Bar {
    friend class FooBar<T>;
};

template<typename T> class Bar2 {
    template<typename T2> friend class FooBar;
};

Then it will compile. The difference is that in Bar<T>, only FooBar<T> is a friend; if you have Bar<int>, only FooBar<int> is a friend, not FooBar<char> or any other type but int. In Bar2<T>, any type of FooBar is a friend.

Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • @q0987: Just because Visual Studio (or any compiler) accepts it doesn't make it valid syntax. – Nicol Bolas Aug 07 '11 at 03:38
  • @q0987 I just checked on Visual Studio 2010 whether my assumption is correct, and apparently it is. Someone tell me if it's just VS that does that. In regards to that compiling in VS 2008, some compilers accept code that is not valid C++. I know it's weird, but it's true. – Seth Carnegie Aug 07 '11 at 03:42
  • @Nicol, I fully agree with you at this point. But I still need a solid answer for my question. – q0987 Aug 07 '11 at 03:43
  • @q0987 is my answer not solid? – Seth Carnegie Aug 07 '11 at 03:43
  • @Seth, your modification changes the meaning of my original code. – q0987 Aug 07 '11 at 03:43
  • @q0987 sometimes compilers will let you have invalid syntax in templates if they are not instantiated. Try instantiating all three template classes and see if you still have no errors. – Seth Carnegie Aug 07 '11 at 03:45
  • 1
    @q0987 see this IdeOne submission: http://ideone.com/Q4CP7 it does error. That is g++, not VS, but again, VS may accept some invalid C++. – Seth Carnegie Aug 07 '11 at 03:45
  • The second code doesn't pass gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5). – q0987 Aug 07 '11 at 03:49
  • @q0987 so then you see it's not valid C++. You really shouldn't use nonstandard stuff like that because if you even upgrade to VS 2010, your code won't compile. Also, try instantiating the templates if you haven't already. Maybe that will trigger the error. Even if it doesn't, it is advisable to use the correct way. – Seth Carnegie Aug 07 '11 at 03:52
  • @Seth, in the first place, I don't know which one is valid. Second, even if you instantiate it in vs2008 as B b; the compiler will compile. – q0987 Aug 07 '11 at 13:40
1

If the Bar2 class definition is modified like below

template<typename T> class Bar2 {
    template<typename U> friend class FooBar<U>;
};

then, anytype of FooBar is friends with anytype of Bar2.

However Bar class definition tells that FooBar with type T is friends with Bar of same type. i.e. Bar < char > & FooBar< char > and not Bar< int > & FooBar< char >

Shash

Shash316
  • 2,218
  • 18
  • 19