The template class constructor accepts an instance of the template class

I have the following situation:

Class Bar { ... } template <class T> class Foo { public: ... Foo(Foo<Bar> bar) { ... } ... } 

Thus, one of the constructors of the Foo class can take an element of the Foo class parameterized by Bar. All this is fine until I create an instance of the Foo class parameterized by Bar, where this constructor is interpreted as a copy constructor, which is not what I want. I am wondering how I can have a constructor taking such an element without interfering with the copy constructor. For example, I can do this:

 template <class T> class Foo { public: ... Foo(Foo<Bar> bar, int unused) { ... } ... } 

And it works fine, because now the constructor does not conflict with the copy constructor. Is there a standard way to solve this problem?

+4
source share
2 answers

If your class template does not need to declare a copy constructor (in general), you can declare the constructor as

 Foo(Foo<Bar> const& bar); 

which will be a conversion constructor in general and a copy constructor for Foo<Bar> . Other specializations will use the implicitly declared copy constructor, where applicable.

Otherwise, creating a template constructor ensures that it is not a special member. In this case, care should be taken that this constructor does not interfere with the copy constructor. This is not nice, but you can do it:

 template<typename U> Foo(U bar, typename boost::enable_if<boost::is_same<U, Foo<Bar> > >::type* = 0); 

This is a constructor that is not a copy constructor and will only be used when arguments of type Foo<Bar> are passed. Note that due to overload resolution rules, the copy constructor Foo<Bar> will be preferable to this constructor.


The previous one is for C ++ 03. Here's a simple C ++ 11 solution:

 template<int = 0> Foo(Foo<Bar>); 
+3
source

This is actually not a valid copy constructor, because copy constructors must follow one of the following four formats:

 MyClass( const MyClass& other ); MyClass( MyClass& other ); MyClass( volatile const MyClass& other ); MyClass( volatile MyClass& other ); 

To make everything work as expected, pass your parameter as a pointer:

 Foo(Foo<Bar>* bar) { // Logic } 

If you pass it by value, you can very well create an infinite loop if your logic mimics a copy constructor.

0
source

Source: https://habr.com/ru/post/1437653/


All Articles