I have such a problem:
when I write:

template<bool b> void foo(void);

template<bool b> class B
{
		friend void foo<b>(void);
};

template<bool b>
void foo(void){};

everything works just fine.
But when I incapsulate all this in another class, I receive errors:

struct C
{
	template<bool b> void foo(void);
	template<bool b> class B
	{
		friend void C::foo<b>(void);
	};
};

template<bool b>
void C::foo(void){};

.
In Visual C++ 2008 I get these errors:
error C2975: 'b' : invalid template argument for 'C::foo', expected compile-time constant expression;
error C2245: non-existent member function 'C::foo' specified as friend (member function signature does not match any overload).

What do I do wrong?

Edited 6 Years Ago by dilas: n/a

Why are you specializing the templates on type bool?

I'm not 100% sure what your intention is but I think i'd start by trying something like this...

template<typename b> 
void foo();

template<typename b>
struct C
{ 
   template<typename b> 
   class B
   {
      friend void foo<b>(void);
   };
};

template<typename b>
void foo(){};

which if you want it to work with bools you would use as follows...

C<bool> c_b;

Some more information on what you actually intend here would be helpful.

Actually, I've just discovered that if I use class-parameter instead of bool-parameter everything works. So boost::bool_<> will do). But the important thing is that we have some kind of compiler's bug here.
What am I going to do?
There is the singleton-like class inside the another singleton-like class. And an object of the inner class can be constructed and destructed only by an object of the outer class.

Actually, I've just discovered that if I use class-parameter instead of bool-parameter everything works. So boost::bool_<> will do). But the important thing is that we have some kind of compiler's bug here.
What am I going to do?
There is the singleton-like class inside the another singleton-like class. And an object of the inner class can be constructed and destructed only by an object of the outer class.

When you say class-parameter do you mean....

template<class b>?

When you say class-parameter do you mean....

template<class b>?

Ok then. That is the same as the solution I posted. The typename and class keywords mean the same in this context. This is not a compiler bug.

What you were doing previously was attempting to do specialised templates for bools, and not quite getting it right. The compiler was complaining because there was no instance of the foo function properly defined.

there was no instance of the foo function properly defined

Aha. For what reason? With type parameter it's defined properly and with constant parameter it's not?

Either of these two is the right way to declare C::foo<> as a friend.

struct C
{
	template < bool B > void foo() ;

	template< bool B > class B
	{
		// ok, the compiler already knows that C::foo 
                // is a template function
		friend void C::foo() ; 

		// more general, tell the compiler explicitly that 
                // we are referring to the template function C::foo
		friend void C::foo <> () ;
	} ;

} ;

template < bool B > void C::foo() {} ;

Aha. For what reason? With type parameter it's defined properly and with constant parameter it's not?

You are attempting an explicit use of a template parameter in the nested class definition...

template<bool b>
class B
{
friend void C::foo<b>(void);
};

Because of this the compiler is unable to determine whether you intend this to match with the previous definition of the function or if you intend a new definiton.

It's worth noting that your original example will compile fine with the friend definition updated to...

friend void C::foo(void);

On a side note, the convention of defining functions which accept no parameters as void, e.g. void func( void );

seems to be largely frowned upon by the C++ community at large. Take it from a reformed C programmer who took a lot of stick over this.

C++ programmers will prefer
void func();

OK
What will you say about this:

struct B
{
    template<class T/*, bool b*/> void foo(void){};


class A
{
    template<class T/*, bool b*/> friend void B::foo(void);
};

};

When I uncomment commented parts it succumbs to the same errors.

Edited 3 Years Ago by mike_2000_17: Fixed formatting

OK. What will you say about this case:

struct B
{
    template<class T/*, bool b*/> void foo(void){};


class A
{
    template<class T/*, bool b*/> friend void B::foo(void);
};

};

When I uncomment commented parts it succumbs to the same errors.

Edited 3 Years Ago by mike_2000_17: Fixed formatting

This article has been dead for over six months. Start a new discussion instead.