1
votes

I have two template declarations as follows:

template < typename T >
      class node {
        public:
          ...
        const unique_ptr < node < T >> & getParent();
        ...
        private:
          ...
        unique_ptr < node < T >> & P; //for parent node
        ...
      };

    template < typename T1, typename T2 >
      class tree {
        public:
          tree(int, T2 & );
        ...
        void travPreord();
        ...
        private:
          ...
      };

Within the definition of the public method

template<typename T1, typename T2> tree<T1,T2>::travPreord() 

I have the following code:

template < typename T1, typename T2 > 
    void tree < T1, T2 > ::travPreord() {

      //lambda definition

      function < void(unique_ptr < node < T1 >> & ) > prntNode = [ & ]
      (unique_ptr < node < T1 >> & pN) {

        ...

        if(auto rPN = pN - > getParent()) {

          ...

        }

      };

    }

For the assignment inside the if statement condition above, I get the following error from the compiler (g++ 4.2.1):

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr >, std::__1::default_delete > > >' if(auto rPN = pN->getParent()){

The arguments to the template instantiation highlighted in the error are supplied from the main():

int main() {

      vector < string > v;

      ...

      tree < string, vector < string >> T(v.size(), v);

      T.travPreord();

      ...

      return 0;

    }

I wrote the if statement condition under question on the following assumptions:

  1. It is possible to assign a unique_ptr to a reference.

  2. The auto keyword should deduce the type of the lvalue expression rPN to be the type of the rvalue expression pN->getParent(), which returns a type unique_ptr<node<T>>&.

So I am not sure about the source of this error.

Could anyone point to the same?

1
If I'm reading the type deduction rules for templates (which auto uses) correctly, the original type, P, has referenceness stripped when determining the deduced type, A (see item #3 after "Before deduction begins, the following adjustments to P and A are made:", which states "If P is a reference type, the type referred to by P is used for deduction."). Basically, auto means value type unless you explicitly make it auto&& or auto&. Using const auto& (and maybe auto&&; my C++ is rusty) should work.ShadowRanger
code snippets with lots of ... are not good to describe a good problem to be StackOverflow solved. Please, illustrate your example with a complete, verifiable and reproducible code. Also, in the question, you refer to a deleted copy constructor, thing that cannot happen, you can delete an instance, or several, but never the copy constructor.... vage questions demand vague responses.... please, correct that.Luis Colorado

1 Answers

3
votes
  1. The auto keyword should deduce the type of the lvalue expression rPN to be the type of the rvalue expression pN->getParent(), which returns a type unique_ptr<node<T>>&.

No, the type will be unique_ptr<node<T>>.

Auto type deduction applies same rules as template argument deduction; the reference part of the expression (i.e. pN->getParent()) is ignored, after that the const part is ignored too. So the result type is unique_ptr<node<T>>.

You need to specify that it's should be a reference explicitly, e.g.

auto& rPN = pN - > getParent() // rPN is of type const unique_ptr<node<T>>&
  1. It is possible to assign a unique_ptr to a reference.

Of course yes. The problem is that rPN is not a reference.