HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

C++11 factory pattern with lambdas

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
factorylambdaswithpattern

Problem

Anonymous functions are one of the best features of C++11. They make everything so beautiful!

However, one can get carried away and start overusing them.

This code calls a function that reads through a file and invokes a callback everytime that something matches a regex. Since I read two different files but I want callbacks only to differ for a constant, I chose this "lambda-returning-lambda" factory pattern.

auto callback_factory = 
    [&] (IPMarkerType start, IPMarkerType stop) -> std::function&)>
{
    return [&,start,stop](IPNode & node){ 
        markers.push_back(IPMarker(node.ip, start));  
        markers.push_back(IPMarker(node.ip.network_ones(node.prefix), stop));
    };
};

read_regexp("C:\\path\\to\\file1.txt", regex, callback_factory(ipm_a_open,ipm_a_close));
read_regexp("C:\\path\\to\\file2.txt", regex, callback_factory(ipm_b_open,ipm_b_close));


Callbacks are really local just to the calling function, so I think that external functor would not be justified. On the other hand, this code smells a lot to me, so I would like to hear your comments.

Solution

First of all, I will assume there is something like template somewhere in your code. Otherwise, I doubt it would compile.

There is something you could do to improve your program: use emplace_back instead of push_back with an object construction. That way, objects will be created right in the collection (list, vector, etc...). By the way, I'll also assume that markers is a standard collection.

auto callback_factory = 
    [&] (IPMarkerType start, IPMarkerType stop) -> std::function&)>
{
    return [&,start,stop](IPNode & node){ 
        markers.emplace_back(node.ip, start);  
        markers.emplace_back(node.ip.network_ones(node.prefix), stop);
    };
};


And, yeah, something still smells: I really wonder how and/or where you declared markers. If it's a global variable, then I think the template parameter may cause some problems.

Code Snippets

auto callback_factory = 
    [&] (IPMarkerType start, IPMarkerType stop) -> std::function<void(IPNode<T>&)>
{
    return [&,start,stop](IPNode<T> & node){ 
        markers.emplace_back(node.ip, start);  
        markers.emplace_back(node.ip.network_ones(node.prefix), stop);
    };
};

Context

StackExchange Code Review Q#14588, answer score: 5

Revisions (0)

No revisions yet.