Okay, so I believe this is a pure c++ mucky syntax question.
I have a class defined with a ptr-to-member as one of its template parameters:
template <class T, T *T::*hook> class My_list {
I have another simple class that is a friend of this class. Usually, I would write:
class My_friend_class {
template <class, class> friend class My_list;
};
...but, because the second template parameter isn't that free...how do I state the friendship?
Thanks!
Maybe a better question is "Why?" rather than "How?"
Exactly what are you trying to achieve? When your C++ code becomes complex and ugly, it is often a warning that you are approaching a problem wrongly.
Related
Compiling the following code
template<typename T>
class t1 {
};
class t1 {
};
Gives the following error
error: template argument required for ‘class t1’
It's literally been years since I've used C++ enough to delve into templates (I've decided to pick it back up and learn C++ 11/14), so I'm probably mistaken, but I thought this was legal.
Can someone advise? If you wanted to do something like this, how would you go about doing it?
No, you can't do this.
Unlike a function template, a class template cannot be overloaded. t1 has been declared as a class template, the only thing you can do is specialize it:
template <>
class t1<int> {
};
You could do something like this with variadic templates:
template<typename...>
struct myclass;
template<>
struct myclass<>{};
template<typename T>
struct myclass<T>{};
But I can think of little use other than template metaprogramming and you still have to use template syntax: myclass<>
In C++ there are 2 template types (to my knowledge): template classes and template functions. Why is it not possible to have a template of template? (be it class, or function, or other template). Has it ever been considered in standards? Does it break C++ syntax/spirit in a way?
I know it may sound crazy, and it's easy to get around.
What is possible with C++:
template<bool b>
class TemplateDependingOnBool
{
public:
template<typename T>
class TheTemplateWeWant{};
}
What would be great:
template<bool b>
template<typename T>
class TheTemplateWeWant{};
and call it in a policy-based style (that's where it's really interesting):
template<typename T, template<typename> class ThePolicy = TheTemplateWeWant<true> >
class Foo {};
The way it's possible to do now is to use:
template<typename T,
template<typename> class ThePolicy = TemplateDependingOnBool<true>::TheTemplateWeWant >
class Foo{};
which is not very elegant.
EDIT:
I know I can template on 2 parameters. The goal is to use the underlying template class (the templated template) as something by itself, be it in a template alias or a template template parameter (as shown in my example).
Policy-based design is a reference to Andrei Alexandrescu's Modern C++ Design, which is the main reason why the feature I'm asking might be useful (because templates are used as template parameters).
With C++11, you're wrong in assuming only two types of templates. There are also type aliases which allow
template <bool b, typename T>
class TheTemplateWeWant { ... };
template<typename T>
using ThePolicy = TheTemplateWeWant<true, T>
If I'm understanding what you're asking correctly (and I'm not entirely clear on your question), then you could write your template taking two parameters:
template <bool b, typename T>
class TheTemplateWeWant { ... };
add a metafunction to partially apply the bool:
template <bool b>
struct PartiallyWant {
template <typename T>
using type = TheTemplateWeWant<b, T>;
};
and then pass that as your policy:
template<typename T,
template<typename> class ThePolicy = PartiallyWant<true>::type >
class Foo { ... };
Foo<char, PartiallyWant<false>::type> foo;
So why not just layer the templates like you propose? The simple answer is that there's no reason to. If TheTemplateWeWant has two template parameters (bool b and typename T, regardless of whether it's an "inner" class or not), then we should express it as such. And if we want to only apply one type or the other, that's something that has fewer use-cases than a general template while also being solvable with just a few lines of boilerplate. Additionally, what if we had such a feature, and now I want to partially apply the T instead of the b? With a few lines of boilerplate I can again accomplish the same thing, but with the layering this would be impossible.
As far as i know you cand you simply that, and it works just as you want - class templated with 2 parameters.
template<bool b, typename T>
class TheTemplateWeWant{}; //valid in C++
What you're describing is partial binding of template parameters, just like std::bind can turn a binary function into a unary function.
For metaprogramming madness, there's Boost.MPL. They do have a template boost::mpl::bind.
I recently came across a c++ piece of code where a class is made friend to itself. As I have read on different forums a class is already a friend to itself. So I was wondering if there is a specific reason why one would want to make a class friend to itself explicitly.
Another question would be, what's the reason in making a class a friend of itself?
Maybe someone with a lot of experience can clarify this topic.
Here is the code example, to illustrate my question:
template < typename T>
class Foo: public T
{
protected:
template < typename U>
friend class Foo;
}
There's no point indeed to make a class a friend to itself, except if it is a template class. For example the following code makes sense:
template <class T>
class A
{
template<class U>
friend class A;
}
An STL example is the std::_Ptr_base which is the base class for std::shared_ptr and std::weak_ptr.
It is not making the class a friend of itself, it is making all classes of that template a friend to all others. So A<Foo> is a friend of A<Bar> which is a different class.
I am surprised the syntax is as you print it and not template<typename U> friend class A<U>; but that is what it actually means.
such is the code:
template<typename,int> class Uoo; //without this will result in complie error,why?
template<typename T>
class Uoo<T,1>
{
};
int main(){
return 0;
}
why Specialized template class need forward declaration?
The following code is a specialisation of a template.
template<typename T>
class Uoo<T,1>
{
};
But you haven't said what the unspecialised form is, and the language requires you to do that. So you need to add the prototype:
template<typename,int> class Uoo;
You don't actually need to declare the unspecialised form since an instance of it is never required. So a prototype is sufficient.
It's not actually a forward declaration that you're making. What you are doing is first defining the "pattern" of the templated class and then you're defining a specialized context or version of it. The better question is, if you didn't have a non-specialized case, then what would be the point of the 2nd template parameter?
As declared, template<typename T> class Uoo<T,1> is a partial specialization of template<typename,int> class Uoo; it fixes the int parameter to 1. It cannot be a partial specialization of a template that doesn't exist.
You could make your "real" class template self-sufficient by writing
template<typename T>
class Uoo
{
...
};
I am writing a small class, the class is basically a factory for the C class, but I want other classes to be able to access some of the methods.
template<class C>
class CFactory {
public:
friend class C;
};
This should make the fields of CFactory available to the class C, but the compiler thinks otherwise.
I'm getting the following two errors using gcc on a mac.
error: using template type parameter 'C' after 'class'
error: friend declaration does not name a class or function
Can anyone tell me what I'm doing wrong and how to get et right?
Unfortunately, in my understanding, this isn't allowed in current standard.
§7.1.5.3/2 says:
[Note: ... within a class template
with a template type-parameter T, the
declaration
friend class T;
is ill-formed. -end note]
On a related note, this restriction seems to be removed in C++0x
(§11.3/3 in N3290).
Incidentally, MSVC may allow this if we write simply friend T;.
Ise's response is correct -- Comeau's FAQ contains a question concerning this issue in more detail.
However, perhaps you can try an extra template indirection that might work? Something like this:
template <typename T>
struct FriendMaker
{
typedef T Type;
};
template <typename T>
class CFactory
{
public:
friend class FriendMaker<T>::Type;
};
This seems to only work with gcc 4.5.x however so I wouldn't rely on it.
C can be anything - int, double, etc. and they are not classes. In general, this class C is not class. And you cannot have something like:
class A
{
friend class int;
//..
};
One more reason to prefer typename, instead of class when using templates