class C
{
struct S
{
T a;
T2 b;
.
.
.
T z;
};
int compute(S s[]);
}
So I need this compute() method to work on the structure S in on of two ways (runtime selectable).
One case is to estimate something on base of a, b and the other contents of structure S, excluding z.
Other times I need the exact same computations, but taking z instead (and in place of) a. They both are the same type and have the same meaning.
The structure S is exposed in the API and thus need to be stored in exactly this layout.
What would be an efficient (compute() is being called rather often) end elegant solution? bool parameter? enum parameter? Template parameter (if so, how to implement it)?
NOTES:
compute() is quite a long function, with selecting a or z happening exactly once
I'd use an enum. It's no more or less efficient than bool, but it may be more clear at the call site:
compute(s, UseAB);
compute(s, UseZB);
Instead of:
compute(s, false);
compute(s, true);
The template option is possible but probably not better; you should try the regular run-time way first. If you care a lot about performance, consider making compute() inline if it is short and simple.
I would just use bool parameter if these are the only two cases. Keep it simple. And document it properly.
Or you can have two methods computeA(S s) and computeZ(S s). In this case it is really about what you are comfortable with.
Related
I am trying to implement a C++ class which will wrap a value (among other things). This value may be one of a number of types (string, memory buffer, number, vector).
The easy way to implement this would be to do something like this
class A {
Type type;
// Only one of these will be valid data; which one will be indicated by `type` (an enum)
std::wstring wData{};
long dwData{};
MemoryBuffer lpData{};
std::vector<std::wstring> vData{};
};
This feels inelegant and like it wastes memory.
I also tried implementing this as a union, but it came with significant development overhead (defining custom destructors/move constructors/copy constructors), and even with all of those, there were still some errors I encountered.
I've also considered making A a base class and making a derived class for each possible value it can hold. This also feels like it isn't a great way to solve the problem.
My last approach would be to make each member an std::optional, but this still adds some overhead.
Which approach would be the best? Or is there another design that works better than any of these?
Use std::variant. It is typesafe, tested and exactly the right thing for a finite number of possible types.
It also gets rid of the type enum.
class A {
std::variant<std::wstring, long, MemoryBuffer, std::vector<std::wstring>> m_data{}; // default initializes the wstring.
public
template<class T>
void set_data(T&& data) {
m_data = std::forward<T>(data);
}
int get_index() { // returns index of type.
m_data.index();
}
long& get_ldata() {
return std::get<long>(m_data); // throws if long is not the active type
}
// and the others, or
template<class T>
T& get_data() { // by type
return std::get<T>(m_data);
}
template<int N>
auto get_data() { // by index
return std::get<N>(m_data);
}
};
// using:
A a;
a.index() == 0; // true
a.set_data(42);
a.index() == 1; // true
auto l = a.get<long>(); // l is now of type long, has value 42
a.get<long>() = 1;
l = a.get<1>();
PS: This example does not even include the coolest (in my opinion) feature of std::variant: std::visit I am not sure what you want to do with your class, so I cannot create a meaningful example. If you let me know, I will think about it.
You basically want QVariant without the rest of Qt, then :)?
As others have mentioned, you could use std::variant and put using MyVariant = std::variant<t1, t2, ...> in some common header, and then use it everywhere it's called for. This isn't as inelegant as you may think - the specific types to be passed around are only provided in one place. It is the only way to do it without building a metatype machinery that can encapsulate operations on any type of an object.
That's where boost::any comes in: it does precisely that. It wraps concepts, and thus supports any object that implements these concepts. What concepts are required depends on you, but in general you'd want to choose enough of them to make the type usable and useful, yet not too many so as to exclude some types prematurely. It's probably the way to go, you'd have: using MyVariant = any<construct, _a>; then (where construct is a contract list, an example of which is as an example in the documentation, and _a is a type placeholder from boost::type_erasure.
The fundamental difference between std::variant and boost::any is that variant is parametrized on concrete types, whereas any is parametrized on contracts that the types are bound to. Then, any will happily store an arbitrary type that fulfills all of those contracts. The "central location" where you define an alias for the variant type will constantly grow with variant, as you need to encapsulate more type. With any, the central location will be mostly static, and would change rarely, since changing the contract requirements is likely to require fixes/adaptations to the carried types as well as points of use.
I am writing a numerical library and I have some algorithms that are based on functions and their derivatives. These have to be provided by the user as functors, e.g.
struct Function{
double operator()(double x, double y){return x*x+y*y);}
};
struct DerivativeX{
double operator()(double x, double y){return 2*x);}
};
//more derivatives...
Now the declaration of my algorithm is e.g.:
template<class F, class F_X, class F_Y>
struct Algorithm
{
Algorithm( F f, F_X fx, F_Y fy):f_(f), fx_(fx), fy_(fy){}
double someFancyComputation( double input) {
//call f_(double,double), fx_(double,double) and fy_(double,double);
private:
F f_;
F_X fx_;
F_Y fy_;
//more other stuff...
};
With all of the STL using templated algorithms and al the fuss about template programming in C++11 I felt really modern and cool using templates.
However, what bugs me now is that in order to use this algorithm a user has to write all template arguments explicitly:
//construct functors
Algorithm<Function, DerivativeX, DerivativeY> alg( f, fx, fy);
(Imagine there were 6 derivatives. That's a lot to write)
Second it's not possible to choose the set of functions (derivatives) at runtime so I am thinking of using Inheritance over templates.
I have two questions:
First, do you think it is a good idea to use inheritance in this case, or are there other design patterns I could use?
Second, I am unfortunately not very experienced with the use and pitfalls of inheritance in a library so could you maybe show or explain how it is properly done for this case?
Edit: so after some research I can come up with
struct aBinaryFunction{
double operator()( double x, double y) = 0;
~aBinaryFunction(){}
};
struct Algorithm{
Algorithm( aBinaryFunction* f, aBinaryFunction* fx, aBinaryFunction* fy):f_(f), fx_(fx), fy_(fy){}
double someFancyComputation( double input) {
//call *f_(double,double), *fx_(double,double) and *fy_(double,double);}
private:
aBinaryFunction * f_, fx_, fy_;
//more other stuff...
};
//in main create functors and then call
Algorithm alg(f,fx,fy);
as a possible implementation. Now, all the users will have to write their functions deriving from my library class and take good care that f fx and fy are still in scope when calling someFancyComputation. Is this good practice or is this considered restrictive? I also feel very uncomfortable with the raw pointers in this code, isn't there a better way to implement this?
In C++, you have many tools...
Template are appropriates when the algorithm is selected at compile-time.
Virtual functions are appropriate for run-time selection.
And there are also many other possibilities in between like std::function, function pointers, member function pointers.
Also, you can replace your constructor call by a make_something function (similar to those in standard library like make_unique, make_shared, make_pair...). By the way, I think that constructor template deduction is planned for a coming standard.
So essentially, if the user select function to use in the algorithm, you have to use a solution based on run-time polymorphism. If the selection is made at compile-time, then the choice is your. Template based solution might be faster as the compiler could optimize that specific case. However, not in all cases it would be useful as it might also increase code size if you have many algorithms used in the same program.
Assuming that someFancyComputation is not trivial and you want to apply the algorithm to either user selection or many compile-time types (like DerivativeX,Y, Z...) solution based on inheritance (or other alternative mentioned above) would be preferable particularily if your algorithm only need to works with doubles.
You could also mixes both approaches as appropriate if some part are dynamic and other static (like maybe using long double).
I have a class
class Point
{
private:
int x; int y;
public:
Point(int a, int b):x(a),y(b){}
Point():Point(0,0){}
}
If I want to sort a vector of Points, shall I use a lambda:
std::sort(xSortedPoints.begin(), xSortedPoints.end(),
[](const cv::Point& p1In, const cv::Point& p2In) -> bool {
return (p1In.x < p2In.x);
});
or using a static function in the class:
std::sort(xSortedPoints.begin(), xSortedPoints.end(), xSorting);
where xSorting is defined and declared in the Point class as
static bool xSorting(const Point& p1In, const Point& p2In)
{
return (p1In.x < p2In.x);
}
Why shall I use lambda, or why not?
EDIT:
Because I need to sort in the two ways (by x and by y) I did not define the < operator.
Based on the comments and answers I need to say that I use this in an application that runs continuously, so the sorting is done a lot of times. So what is better to use in my case: static or lambdas? Lambdas are created every time the std::sort is used? If yes, than I think static is the best choice... No?
Lambdas are there for convenience and slick code.
If you prefer to use a static function you should do this. If you use it once consider a lambda.
To my knowledge there is no performance gain when using lambdas.
So either do a static function, put an in place lambda or define less than operator for the class.
Lambda would make the code more concise especially if it's a one-liner like in your case. On the other hand, I would think the static function approach would be prefered if it needs to or can be used in more than 1 place.
This is kind of opinion based but in short:
If it is short and not used often, use a lambda. Your example is short enough. If the function is long or complicated or used often, give it a name.
In this special case, you could think about overloading operator < for Point if it makes sense. Then, no third argument to sort would be required, but you have make sure that < does what the naive reader would expect.
Btw, you can omit the ->bool, the compiler will deduce it automatically.
I don't know if there is any performance issues here, and the answers you get are going to be of the type "IM(H)O ....", so here are my two cents:
In this case, lambda is good in the sense that it shows the person who is reading the code what you mean by comparing two points. Mathematically, 2D (or any higher dimensions for that matter) points don't form an ordered set, so a < operator will be confusing. Having a static function, friend, ... on the other hand puts the definition of the comparison too far from the usage and, again, might add to confusion as the reader has to scroll to the definition to see what you mean by comparing two points.
I'm passing a function, f, to another function, SInf, but the 20+ times I call f in SInf, I call f(1./x)/(x*x).
Is there a way to have another function, say g(x)=f(1./x)/(x*x)? Though I guess not necessary to complete what I need to do, it would dramatically improve readability of the code.
I would rather not have a class or struct external to SInf, since I want it to be able to replace similar functions.
double SInf(double (*f)(double), int N, double aa, double bb, bool closed=true)
{
struct functions{
double fi(double x){return f(1./x)/(x*x);}
};
//bla bla lots of code
}
gives me
error: use of parameter from containing function
You can do things like this easily with std::function and lambda functions. It will be difficult otherwise, as you'll have no way to pass additional arguments.
If you are writing an uncomplicated single-threaded app, you can still use regular function pointers and pass the extra state via globals, but that breaks down in a hurry when programs get complicated.
StilesCrisis is correct that lambdas are a good (if not the best) way of solving this. Here's what you can do:
//define a function g
auto g = [&f] (double _x) {return f(1./_x)/(_x*_x);};
//call g
g(x);
If you are unfamiliar with this syntax, I suggest you read this article first. In particular, take a look at the "variable capture with lambdas" section.
Say I wanted to have one variable in a class always be in some relation to another without changing the "linked" variable explicitly.
For example: int foo is always 10 less than int bar.
Making it so that if I changed bar, foo would be changed as well. Is there a way to do this? (Integer overflow isn't really possible so don't worry about it.)
Example: (Obviously doesn't work, but general code for an understanding)
class A
{
int x;
int y = x - 10; // Whenever x is changed, y will become 10 less than x
};
No, you can't do that. Your best option for doing this is to use accessor and mutator member functions:
int getFoo()
{
return foo_;
}
void setFoo(int newFoo)
{
foo_ = newFoo;
}
int getBar()
{
return foo_ + 10;
}
void setBar(int newBar)
{
foo_ = newBar - 10;
}
This is called an invariant. It is a relationship that shall hold, but cannot be enforced by the means provided by the programming language. Invariants should only be introduced when they are really necessary. In a way the are a relatively "bad" thing, since they are something that can be inadvertently broken. So, the first question you have to ask yourself is whether you really have to introduce that invariant. Maybe you can do without two variables in this case, and can just generate the second value from the first variable on the fly, just like James suggested in his answer.
But if you really need two variables (and very often there's no way around it), you'll end up with an invariant. Of course, it is possible to manually implement something in C++ that would effectively link the variables together and change one when the other changes, but most of the time it is not worth the effort. The best thing you can do, if you really need two variables, again, is to be careful to keep the required relationship manually and use lots of assertions that would verify the invariant whenever it can break (and sometimes even when it can't), like
assert(y == x - 10);
in your case.
Also, I'd expect some advanced third-party C++ libraries (like, Boost, for example) to provide some high level assertion tools that can be custom-programmed to watch over invariants in the code (I can't suggest any though), i.e. you can make the language work for you here, but it has to be a library solution. The core language won't help you here.
You could create a new structure which contains both variables and overload the operators you wish to use. Similar to James McNellis' answer above, but allowing you to have it "automatically" happen whenever you operate on the variable in question.
class DualStateDouble
{
public:
DualStateDouble(double &pv1,double &pv2) : m_pv1(pv1),m_pv2(pv2)
// overload all operators needed to maintain the relationship
// operations on this double automatically effect both values
private:
double *m_pv1;
double *m_pv2;
};