Related
I have function below.
template<typename TypeBasedOnMonth, typename TypeBasedOnWeekday>
DoWork(){}
User provides input based on which T1 and T2 can be determined. I can have nested switch to have the DoWork invocation as below which I want to avoid.
switch (month)
{
case Month1:
{
switch (weekday)
{
case Weekday1:
DoWork<TypeMonth1, TypeWeekday1>();
}
...
case Month2:
...
}
}
The above is leading to writing m*n invocation of DoWork ? Any better ways ?
The short answer is "no". At least in this respect, C++ is a statically-typed language. Data types are bound to their objects at compile time, rather than at runtime, as you are attempting to do here.
Having said all that:
1) The given details are sparse, but it's quite possible that after reviewing what problem you are really trying to solve here, there's a different, cleaner solution. You just think that this is the answer to the original issue you are attempting to implement, and are trying to figure out how to implement it. A completely different approach to the given task at hand will probably result in a cleaner approach.
2) If all else fails, then it's time for an Automatic Spaghetti Code Generator[tm] to come to the rescue. Using a saved list of source enumerations, it shouldn't be difficult to write a quick little Perl script, or maybe an XSLT stylesheet, if working with XML-based data, to robo-generate canned skeleton code for the body of the switch, instead of doing it manually.
Some schools of thought might frown on this approach, but I just believe in using the right tool, for the right job. There are times when it makes sense to integrate an Automatic Spaghetti Code generator as part of the software build.
After all, what is Lex, or Yacc, if not an Automatic Spaghetti Code generator? Those very useful, and time-tested tools swallow a definition of a lexical tokenizer, or a language grammar, given in a specific, compact, precise form, and spit out a bunch of spaghetti code that implement a lexical analyzer, and a grammar parser.
If it's good for the goose, it's good for the gander, I say. If you can't come up with a different, cleaner solution for this, just write your own Automatic Spaghetti Code generator, for the task.
It strikes me that a response may take on patterns of weekdays, or some patterns of months. This forms a 2d grid of 12 months by 7 days, and out of the 84 possibilities it is likely you intend many repeats.
What looks slightly better to me is a grid of function objects. Let's say out of the 84 possibilities, many are "DoNothing" days, whereas every Friday is "DoFriday", and something like "VacationMonday" is only done in summer months. With grid of function objects, empty cells would automatically be "DoNothing", whereas you could plug in function objects for certain combinations. A grid could be synthesized by a nested vector or array, perhaps:
typedef std::array< std::array< std::shared_ptr< Worker >, 7 >, 12 > WorkGrid;
Each cell would either be empty, or fitted with a "virtual functor". A base, worker, would be something like:
struct Worker
{
virtual void operator()(){};
};
struct VacationMonday : public Worker
{
virtual void operator()() { ...do VacationMondayStuff...}
};
If there are more than a few different things to do, however, you may prefer a series of member functions, then use a pointer to member function (or maybe you prefer std::function) to call various member functions based on which is plugged into a cell.
template< typename O >
struct VWorker : public Worker
{
O * Obj;
void (O::*Func)();
virtual void operator()() { (Obj->*Func)(); }
VWorker( O *o, void ( O::*f )() ) : Obj( o ), Func( f ) {}
};
As an alternative to the grid concept, you could use a map where the two integers are keys, perhaps based on a std::tuple.
For this you would search the map for a matching tuple to find what functor to call. Consider these snippets:
typedef std::tuple< int, int > Itpl;
typedef std::shared_ptr< Worker > WPtr;
typedef std::map< Itpl, WPtr > WorkMap;
Defining the map and associated types. Then, assuming a class WorkObj with a collection of member functions to be called based on which Month/Day pair is to be searched, you'd declare the map with something like:
WorkMap wm;
Probably as a member of WorkObj, and subsequently populate the map in the constructor (or an initializer member function ) of WorkObj with something like:
wm[ Itpl( Month2, Weekday1 ) ]
= WPtr( new VWorker< WorkObj >( this, &WorkObj::MemFunc ) );
Note, my use of a virtual object base, Worker, with a derived template calling a member function via function pointer is an old fashioned approach now solved with std::function (and possibly uses of std::bind), so there are myriad ways of doing this, some dependent on what version of C++ you're supporting (especially pre or post C++11). Some of used boost for this support while waiting for C++11 support, some of us made our own (even earlier).
These are merely illustrations (no code was tested here) to suggest ways in which selecting a function (or, therefore, some act) based on data is often implemented. What you're inquiring about is more generalized in solutions for message maps in GUI applications, in order to interpret GUI messages, like mouse actions or button clicks, into function calls. The now outdated technique of creating a table of response functions with macros has been replaced in most GUI frameworks with a more dynamic database of function objects which usually resolve into calling member functions of classes representing Windows in a GUI.
By introducing an intermediate single-parameter function template, it will write m calls to DoWork() and n calls to DoWork().
template<typename TypeBasedOnMonth>
DoWork(TypeBasedOnWeekday weekday)
{
switch (weekday)
{
case Weekday1:
DoWork<TypeBasedOnMonth, TypeWeekday1>();
break;
case Weekday2:
DoWork<TypeBasedOnMonth, TypeWeekday2>();
...
}
...
}
int main()
{
...
switch (month)
{
case Month1:
DoWork<TypeMonth1>(weekday);
break;
case Month2:
DoWork<TypeMonth2>(weekday);
...
}
...
}
I have a complex algorithm. This uses many variables, calculates helper arrays at initialization and also calculates arrays along the way. Since the algorithm is complex, I break it down into several functions.
Now, I actually do not see how this might be a class from an idiomatic way; I mean, I am just used to have algorithms as functions. The usage would simply be:
Calculation calc(/* several parameters */);
calc.calculate();
// get the heterogenous results via getters
On the other hand, putting this into a class has the following advantages:
I do not have to pass all the variables to the other functions/methods
arrays initialized at the beginning of the algorithm are accessible throughout the class in each function
my code is shorter and (imo) clearer
A hybrid way would be to put the algorithm class into a source file and access it via a function that uses it. The user of the algorithm would not see the class.
Does anyone have valuable thoughts that might help me out?
Thank you very much in advance!
I have a complex algorithm. This uses many variables, calculates helper arrays at initialization and also calculates arrays along the way.[...]
Now, I actually do not see how this might be a class from an idiomatic way
It is not, but many people do the same thing you do (so did I a few times).
Instead of creating a class for your algorithm, consider transforming your inputs and outputs into classes/structures.
That is, instead of:
Calculation calc(a, b, c, d, e, f, g);
calc.calculate();
// use getters on calc from here on
you could write:
CalcInputs inputs(a, b, c, d, e, f, g);
CalcResult output = calculate(inputs); // calculate is now free function
// use getters on output from here on
This doesn't create any problems and performs the same (actually better) grouping of data.
I'd say it is very idiomatic to represent an algorithm (or perhaps better, a computation) as a class. One of the definitions of object class from OOP is "data and functions to operate on that data." A compex algorithm with its inputs, outputs and intermediary data matches this definition perfectly.
I've done this myself several times, and it simplifies (human) code flow analysis significantly, making the whole thing easier to reason about, to debug and to test.
If the abstraction for the client code is an algorithm, you
probably want to keep a pure functional interface, and not
introduce additional types there. It's quite common, on the
other hand, for such a function to be implemented in a source
file which defines a common data structure or class for its
internal use, so you might have:
double calculation( /* input parameters */ )
{
SupportClass calc( /* input parameters */ );
calc.part1();
calc.part2();
// etc...
return calc.results();
}
Depending on how your code is organized, SupportClass will be
in an unnamed namespace in the source file (probably the most
common case), or in a "private" header, included only by the
sources involved in the algorith.
It really depends of what kind of algorithm you want to encapsulate. Generally I agree with John Carmack : "Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function."
It really boils down to: do the algorithm need access to the private area of the class that is not supposed to be public? If the answer is yes (unless you are willing to refactor your class interface, depending on the specific cases) you should go with a member function, if not, then a free function is good enough.
Take for example the standard library. Most of the algorithms are provided as free functions because they only access the public interface of the class (with iterators for standard containers, for example).
Do you need to call the exact same functions in the exact same order each time? Then you shouldn't be requiring calling code to do this. Splitting your algorithm into multiple functions is fine, but I'd still have one call the next and then the next and so on, with a struct of results/parameters being passed along the way. A class doesn't feel right for a one-off invocation of some procedure.
The only way I'd do this with a class is if the class encapsulates all the input data itself, and you then call myClass.nameOfMyAlgorithm() on it, among other potential operations. Then you have data+manipulators. But just manipulators? Yeah, I'm not so sure.
In modern C++ the distinction has been eroded quite a bit. Even from the operator overloading of the pre-ANSI language, you could create a class whose instances are syntactically like functions:
struct Multiplier
{
int factor_;
Multiplier(int f) : factor_(f) { }
int operator()(int v) const
{
return v * _factor;
}
};
Multipler doubler(2);
std::cout << doubler(3) << std::endl; // prints 6
Such a class/struct is called a functor, and can capture "contextual" values in its constructor. This allows you to effectively pass the parameters to a function in two stages: some in the constructor call, some later each time you call it for real. This is called partial function application.
To relate this to your example, your calculate member function could be turned into operator(), and then the Calculation instance would be a function! (or near enough.)
To unify these ideas, you can try thinking of a plain function as a functor of which there is only one instance (and hence no need for a constructor - although this is no guarantee that the function only depends on its formal parameters: it might depend on global variables...)
Rather than asking "Should I put this algorithm in a function or a class?" instead ask yourself "Would it be useful to be able to pass the parameters to this algorithm in two or more stages?" In your example, all the parameters go into the constructor, and none in the later call to calculate, so it makes little sense to ask users of your class make two calls.
In C++11 the distinction breaks down further (and things get a lot more convenient), in recognition of the fluidity of these ideas:
auto doubler = [] (int val) { return val * 2; };
std::cout << doubler(3) << std::endl; // prints 6
Here, doubler is a lambda, which is essentially a nifty way to declare an instance of a compiler-generated class that implements the () operator.
Reproducing the original example more exactly, we would want a function-like thing called multiplier that accepts a factor, and returns another function-like thing that accepts a value v and returns v * factor.
auto multiplier = [] (int factor)
{
return [=] (int v) { return v * factor; };
};
auto doubler = multiplier(2);
std::cout << doubler(3) << std::endl; // prints 6
Note the pattern: ultimately we're multiplying two numbers, but we specify the numbers in two steps. The functor we get back from calling multiplier acts like a "package" containing the first number.
Although lambdas are relatively new, they are likely to become a very common part of C++ style (as they have in every other language they've been added to).
But sadly at this point we've reached the "cutting edge" as the above example works in GCC but not in MSVC 12 (I haven't tried it in MSVC 13). It does pass the intellisense checking of MSVC 12 though (they use two completely different compilers)! And you can fix it by wrapping the inner lambda with std::function<int(int)>( ... ).
Even so, you can use these ideas in old-school C++ when writing functors by hand.
Looking further ahead, resumable functions may make it into some future version of the language (Microsoft is pushing hard for them as they are practically identical to async/await in C#) and that is yet another blurring of the distinction between functions and classes (a resumable function acts like a constructor for a state machine class).
What's everybody's opinion on using lambdas to do nested functions in C++? For example, instead of this:
static void prepare_eggs()
{
...
}
static void prepare_ham()
{
...
}
static void prepare_cheese()
{
...
}
static fry_ingredients()
{
...
}
void make_omlette()
{
prepare_eggs();
prepare_ham();
prepare_cheese();
fry_ingredients();
}
You do this:
void make_omlette()
{
auto prepare_eggs = [&]()
{
...
};
auto prepare_ham = [&]()
{
...
};
auto prepare_cheese = [&]()
{
...
};
auto fry_ingredients = [&]()
{
...
};
prepare_eggs();
prepare_ham();
prepare_cheese();
fry_ingredients();
}
Having come from the generation that learned how to code by using Pascal, nested functions make perfect sense to me. However, this usage seemed to confuse some of the less experienced developers in my group at work during a code review where I made use of lambdas in this way.
I don't see anything wrong with nested functions per se. I use lambdas for nested functions, but only if it meets some conditions:
It is called in more than once place. (otherwise just write the code directly if it's not too long)
It is really an internal function, so that that calling it in any other context would not make sense.
It's short enough (maybe 10 lines max).
So in your example I would not use lambdas for reason number one.
Conceptually nested functions can be useful for the same reason why private methods in classes are useful. They enforce encapsulation and they make it easier to see the structure of the program. If a function is an implementation detail to some other function then why not make it explicitly so?
The biggest problem I see is with readability; it's more difficult to read code that has a lot of nesting and indenting. Also, people are not very comfortable with lambdas yet so resistance is expected.
For any given piece of code, make it as visible as necessary and as hidden as possible:
If the piece of code is used in only one place, write it there.
If it is used in multiple places inside the same function, emulate nested functions through lambdas.
If it is used by multiple functions, put it in a proper function.
You can already guess that you're doing something unorthodox by the comments you received. This is one of the reasons C++ has bad reputation, people never stop abusing it. Lambdas are mainly used as inline function objects for standard library algorithms and places that require some kind of callback mechanism. I think this covers 99% of use-cases, and it should stay that way!
As Bjarne said in one of his lectures: "Not everything should be a template, and not everything should be an object."
And not everything should be a lambda :) there is nothing wrong with a free standing function.
It's a very limited use case. For starters, the functionality present in the local function must be needed at several spots inside the enclosing function such that the resulting local refactoring will be a win in readability. Otherwise I will write the functionality inline, perhaps putting it in a block if that helps.
But at the same time, the functionality must be local or specific enough that I don't have an incentive to refactor the functionality outside of the (not so) enclosing function, where I could perhaps reuse it entirely in another function at some point. It must also be short: otherwise I'm just going to move it out, perhaps putting it in an anonymous namespace (or namespace detail in a header) or some such. It doesn't take much for me to trade locality off in favour of compactness (long functions are a pain to review).
Note that the above is strictly language agnostic. I don't think C++ spins a particular spin on that. If there is one particular C++ advice I have to give on the topic however, it's that I would proscribe using a default by-reference capture ([&]). There'd be no way to tell if that particular lambda expression describe a closure or a local function without carefully reviewing the whole body. Which wouldn't be that bad (it's not that closures are 'scary') if not for the fact that that by-reference captures ([&], [&foo]) allow mutations even if the lambda is not marked mutable, and by-value captures ([=], [foo]) can make an undesirable copy, or even attempt an impossible copy for move-only types. All in all I'd rather not capture anything at all if it's possible (that's what parameters are for!), and use individual captures when needed. It's especially problematic
To sum up:
// foo is expensive to copy, but ubiquitous enough
// that capturing it rather than passing it as a parameter
// is acceptable
auto const& foo_view = foo;
auto do_quux = [&foo_view](arg_type0 arg0, arg_type1 arg1) -> quux_type
{
auto b = baz(foo_view, arg0, arg1);
b.frobnicate;
return foo_view.quux(b);
};
// use do_quux several times later
In my opinion it's useless, but you can accomplish that using only C++03
void foo() {
struct {
void operator()() {}
} bar;
bar();
}
But once again, IMHO it's useless.
I have a number of algorithms for community detection on graphs that I want to now visualise them. This visualisation requires me to 'hijack' these algorithms while they execute and log what they are doing. Specifically this will mean passing a reference to a std::vector<graph_partition> as an argument to these algorithms, and appending to that vector as the algorithm proceeds.
Therefore to each algorithm (which are typically just functions), I would need to add a further argument for the &std::vector<graph_partition>, and one or two lines of code for the logging.
I will not always want/need to log however, and so doing this in an intelligent way has proved non-trivial. I have thought of:
Write separate logging versions of each algorithm: The problem here is that I'll be repeating myself massively, since 95% of the logging and non-logging functions will be the same. You could say my code should be so modular that no repetition should occur, but in practice unless I have lots of tiny trivial functions I would have to repeat myself.
Have single function with a conditional argument to decide whether to log or not: Problem is what do I pass for &std::vector<graph_partition> when I don't want to use it? Also (probably minuscule) runtime hit of continuously evaluating conditional.
Some macro wizardry: Macros are a bit evil and would prefer to avoid them if possible.
Just log by default, discard if I don't need it: Convenient but wasteful, both in terms of runtime and space.
Any ideas or thoughts on these would be appreciated.
If you fancy using templates, I don't think you really need variadic templates. If you're happy to recompile in order to switch logging on and off:
struct NoLogging {
void log(const graph_partition &) {}
};
struct Logging {
std::vector<graph_partition> vec;
void log(const graph_partition &p) {
vec.push_back(p);
}
};
template <typename Logger>
void some_algorithm(Logger &logger) {
// do some stuff
logger.log(something);
}
// optionally, for convenience
void some_algorithm() {
NoLogging l;
some_algorithm(l);
}
// user writes:
some_algorithm();
// or
Logging l;
some_algorithm(l);
// do something with l.vec
The difference between this and "just log by default, even if I don't need it", is that an even vaguely decent compiler will completely remove the calls to log in some_algorithm<NoLogging>, because it can see that they do nothing.
If you don't want to have to recompile, you could have a runtime switch between the two different sets of instantiations - it may or may not be convenient to do this via some polymorphic interface that provides all the algorithms and has two derived classes, from a template like so:
template <typename Logger>
struct ConcreteAlgorithms : public Algorithms {
Logger logger;
static void some_algorithm() {
::some_algorithm(logger);
}
// more algorithms
};
Algorithms *get_algorithms(bool with_logging) {
if (with_logging) {
return new ConcreteAlgorithms<Logging>;
} else {
return new ConcreteAlgorithms<NoLogging>;
}
}
However, at this point you're going to have the code bloat of two different versions of the algorithms, so you might prefer to make the logger polymorphic and take the (probably tiny) runtime overhead instead, as per Mark's answer.
Pass a pointer to a parent logging class to each function. Have a child of the logging class that implements the logging function as a do-nothing, and use that one when you don't need logging. The real logging class would also be a child, and would contain the vector or a reference to it.
I was having a look at the "Function" class documentation in Boost, and stumbled across this:
boost::function<float (int x, int y)> f;
I must admit this syntax is highly confusing for me. How can this be legal C++ ?
Is there any trick under the hood ? Is this syntax documented anywhere?
[Edit] This is an answer to the author's original, unedited question which was actually two questions.
I must admit this syntax is highly
confusing for me. How can this be
legal C++ ? :) Is there any trick
under the hood ? Is this syntax
documented anywhere ?
This is perfectly legal and it's actually not too complicated.
template <class T>
class C
{
public:
T* function_pointer;
};
void fn(int x)
{
cout << x << endl;
}
int main(int argc, char** argv)
{
C<void (int x)> c;
c.function_pointer = &fn;
c.function_pointer(123); // outputs x
}
It's basically the same thing as doing:
typedef void Function(int);
C<Function> c;
This type is not just applicable C++, it's just as applicable in C (the actual type C is parameterized to). The template magic here is taking something like the Function typedef here and being able to detect the types of the return values and arguments. Explaining that would be too lengthy here and boost::function uses a lot of the function traits meta-templates in boost to retrieve that information. If you really want to spend the time to learn this, you should try to understand the boost implementation starting with boost::function_traits in Boost.Type Traits.
However, I want to address your general problem. I think you are trying too hard to simplify a couple of lines of perfectly acceptable code. There's nothing wrong with passing the arguments for your command subclasses through their parameterized subclass constructors. Is is really worth trying to involve typelists and boost::function-like solutions here, thereby increasing compile times and code complexity significantly, just for that?
If you want to reduce it further, just write an execute function that will execute any command subclass and add it to the undo stack and so on:
typedef boost::shared_ptr<Command> CommandPtr;
void execute(const CommandPtr& cmd)
{
cmd->execute();
// add command to undo stack or whatever else you want to do
}
// The client can simply write something like this:
execute(CommandPtr(new CmdAdd(some_value) );
I really think the trade-off of trying to make it any more complicated isn't worth it. The boost authors wanted to write an extremely general-purpose solution for boost::function which would be used by many people across many platforms and compilers. However, they didn't try to generalize a command system capable of executing functions with different signatures across a unified undo system (thereby requiring the state of these commands to be preserved even after one is initially finished calling them and be able to undo and re-execute them without re-specifying the original state data on subsequent executions). For that, your inheritance-based approach is most likely the best and most straightforward one.