C++ Replaces Deleter of unique_ptr with lambda

Keywords: C++ Lambda Programming

C++ Replaces Deleter of unique_ptr with lambda

Code

#include <iostream>
#include <cstdlib>
#include <memory>
#include <string>
#include <functional>

using namespace std;

class go
{
public:
    go() {}
    ~go()
    {
        cout << "go die.\n";
    }
};

auto d = [] ( go * gp )
{
    delete gp;
    cout << "deletor done.\n";
};

class go_de
{
public:
    void operator() ( go* g )
    {
        d ( g );
    }
};

int main()
{
    {
        unique_ptr < go, go_de > b{ new go{} };//1
    }
    {
        //unique_ptr < go, decltype (d) > b{ new go{}}; complie error //2
        unique_ptr < go, decltype (d) > a{ new go{}, d };//3
    }
    {
        unique_ptr < go, function<void(go*) > > a{ new go{}, d };//4
        //i.e. unique_ptr < go, function<void(go*) > > a{ new go{}, [](go*gp) {delete gp;cout << "deletor done.\n"; }};
    }
    system ( "pause" );
    return 0;
}

describe

Generally, when you need to give a template's Concept parameter, you pass in a type that implements the Concept just like the implementation of Code 1. For example, go_de implements the unique_ptr template parameter Deletor.
Today I want to try to pass in the type of lambda expression as a template parameter, but I find that it is not possible. The reason lies in

c++14 draft n4269
5.1.2 Lambda expressions
20 The closure type associated with a lambda-expression has no default constructor and a deleted copy assignment operator. It has a defaulted copy constructor and a defaulted move constructor (12.8). [ Note: These special member functions are implicitly defined as usual, and might therefore be defined as deleted. end note ]

This means that the lambda expression has no default constructor and operator = is also set to deleted. There is only one default copy constructor and move constructor. Obviously, the implementation of unique_ptr must have used the default constructor of Deletor Concept. So the compilation failed. This is in
unique_ptr constructor page It's clearly written.

2) Constructs a std::unique_ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter. Requires that Deleter is DefaultConstructible and that construction does not throw an exception.2) Constructs a std::unique_ptr which owns p, initializing the stored pointer with p and value-initializing the stored deleter. Requires that Deleter is DefaultConstructible and that construction does not throw an exception.

Imagine unique_ptr (pointer p, d1); if the constructor does not exist, then the Lambda type cannot be introduced as Concept.

summary

  • To use the type of Lambda expression as Concept, decltype is derived by type.
  • Lambda has no default constructor, copy assignment operator.
  • When writing C++ library, if we use template and C oncept technology, we should consider adding C oncept object as constructor of parameter type so as not to restrict Lambda expression type to be imported as C oncept.
    After all, the principle of C++ language design is to try not to restrict the programming methods of C++ language users.

Posted by phithe on Sun, 10 Feb 2019 11:57:17 -0800