I have a problem of calling the constructors in boost::variant.
Suppose I have two classes "abc" and "asd" and I have an object declaration something like-
class abc
{
int var;
float var2;
public: abc(int a)
{
var = a;
}
public: abc(inta, float b)
:var(a), var2(b)
{}
};
class asd
{
int var;
public: asd(int a)
{
var = a;
}
};
typedef boost::variant<abc,asd> def;
int main()
{
def my_object;
}
my problem is how do I call the constructor of the object my_object?
From the manual (you must have missed it):
a variant can be constructed directly from any value convertible to
one of its bounded types
And:
Similarly, a variant can be assigned any value convertible to one of
its bounded types
So:
def my_object = asd(3); // or `def my_object(asd(3));`
my_object = abc(4);
A variant is not some multiply-derived custom type, and has its own constructors defined instead. The idiomatic way is to just assign one of the variant types:
typedef boost::variant<abc,asd> def;
int main()
{
def my_object = abc(1);
my_object = abc(1, .4);
}
If you wanted to actually use constructor without without copy-initialization (allthough most compilers will elide the copy) you can write:
def my_object(abc(1,.4));
Related
I have a class that has function pointer to kernel function, that can change from outside.
class Bar
{
public:
int i;
}
class Foo
{
public:
std::function<double()> kernel;
Bar bar;
};
int main()
{
Foo f;
f.kernel = []() -> double { return i * i; }; //this is not working obviously
}
How can I achieve behaviour that is "presented", eg. read class variables inside lambda. I can bypass it by passing f inside and write f.bar.i, but that is not very nice solution.
In C++14 you can write it as,
f.kernel = [&i = f.bar.i]() -> double { return i * i; };
If you don't have C++14, you can alternatively create another variable,
int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };
Though there's nothing wrong with passing f and writing f.bar.i.
It seems that you cannot do so.
There is no construct to create a member function lambda.
But you probably can follow #KerrekSB's suggestion and in addition to that dispatch the call to still get the member function:
class Foo
{
public:
double kernel()
{
_kernel(*this);
}
std::function<double(Foo &)> _kernel;
};
Foo f;
f._kernel = [](Foo &f) -> double { return f.i * f.i; };
f.kernel()
Note that you cannot name both fields kernel.
The lambda function does not know about i or Bar. How could it know? You need to pass a Reference. If you define the function body differently so you can pass i as parameter and you call it within the class you should get what you want.
I have a class that has a constructor taking quite a few parameters
enum class FooType {FOO_A, FOO_B, FOO_C};
class Foo {
Foo(const double a, const double b, .... const double n);
}
depending on the 'type', I only need a certain subset of the params. At the moment there are various constructors with different number of inputs, but some new types will be added so that the number of inputs is the same. I could just add the type to the constructor, have a long switch in it, but the params list is quite long.
Foo(FooType type, const double a, const double b, .... const double n) {
if (type = FooType::FOO_A) {
...
} else if ....
}
Doesn't seem too bad, but I also don't like having that long parameter list. Seems to easy to make typos that are a pain to debug. So I can
a.) pass a structure in
b.) do something else
and I am just curious about potential b solutions.
Is it possible to templateize this such that I could create a template constructor and call the constructor with something like
std::make_shared<Foo<FooType::FOO_A>>(a, b, c);
Note: I don't want to use inheritance since the rest of the class' functionality has absolutely no use/need for it.
This could be a use case for the named parameters idiom: http://www.cs.technion.ac.il/users/yechiel/c++-faq/named-parameter-idiom.html .
That would allow your constructor call to look like this:
File f = OpenFile("foo.txt")
.readonly()
.createIfNotExist()
.appendWhenWriting()
.blockSize(1024)
.unbuffered()
.exclusiveAccess();
Instead of the above example, you could have a helper class that contains all the named parameters and your class constructor would take an instance of the parameters class as its parameters.
This lets you freely pick the set of parameters that you initialize at construction time. If you want to enforce different subsets being initialized for the different types, then you should just write different constructor versions.
Here is how you could make a templated constructor using a builder pattern:
class Foo {
double a;
int b;
double c;
public:
Foo(double a, int b, char c) {
}
};
template <FooType Type>
class Builder { };
template <>
class Builder<FooType::FOO_A> {
double _a;
public:
Builder& a(double val) { _a = val; return *this; }
Foo build() { return { _a, 0, 0 }; }
};
template <>
class Builder<FooType::FOO_B> {
int _b;
public:
Builder& b(int val) { _b = val; return *this; }
Foo build() { return { 0.0, _b, 0 }; }
};
template <>
class Builder<FooType::FOO_C> {
char _c;
public:
Builder& c(char val) { _c = val; return *this; }
Foo build() { return { 0.0, 0, _c }; }
};
The Builder class is templated as you wanted and the code you were executing in that if else statement, you can execute in builder's constructor or the build function on the instance of Foo you will be returning.
In the example a is relevant for FOO_A, b is relevant for FOO_B and c for FOO_C and other values get initialized to their default value.
This is how you would use it:
int main() {
Foo testA = Builder<FooType::FOO_A>().a(12.5).build();
Foo testB = Builder<FooType::FOO_B>().b(10).build();
Foo testC = Builder<FooType::FOO_C>().c('x').build();
return 0;
}
It is a pretty small example for a builder pattern, but from your example it seems like you are using much more arguments. To add another argument to any of the builder specializations in form Builder& typeName(Type val) { _typeName = val; return *this; } (it should return self reference so these funtions can be chained).
I believe that anything uninitialized gets automatically initialized and that this is somewhat dangerous (and poor practice). I also understand that initialization lists are generally more efficient (and in some cases necessary), however, I wanted to verify some parameters via a function call, before assigning them to a member variable.
For example, using the typical assignment constructor, I'd have something like this:
class MyObj
{
private:
int one_;
int two_;
DiffObj diffObj_;
... // other stuff
}
MyObj::MyObj(int a, int b, std::string type, std::vector<double> params)
{
one_ = a;
two_ = b;
if (verifyType(type, params))
{
diffObj_ = createDiffObj(params);
}
}
With this situation though, how could I utilize an initialization list? I thought perhaps by initializing some of the parameters in the constructor and using a separate call to initialize the rest, but I am not quite sure if that is kosher.
MyObj::MyObj(int a, int b) :
one_(a),
two_(b)
{}
MyObj::initializeDiffObj(std::string type, std::vector<double> params)
{
if (verifyType(type, params))
{
diffObj_ = createDiffObj(params);
}
}
Something like this would be perfectly reasonable. You can have an initializer-list and do some work inside your constructor, you do not have to pick one.
class MyClass {
public:
MyClass(int a, SomeStruct b)
: _a(a) {
if (isValid(b)) {
// Initialize _b
_b = createWeirdThingFromSomeStruct(b);
}
}
private:
int _a;
WeirdThing _b;
};
If your constructor does not provide an initializer for a member, that member is default-initialized. For int that means no initialization at all; for class types with a user-provided constructor it means to call that constructor.
Ideally the constructor-initializer list should do all the initializing of members. Here is one way to do it for your situation:
MyObj::MyObj(int a, int b, std::string type, std::vector<double> params)
: one_(a), two_(b),
diffobj( verifyType(type, params), std::move(params) )
{
}
This (ab)uses the comma operator to fit in the call to verifyType during the initialization of diffobj. The verifyType function should throw an exception if verification fails.
Ok, it's been a while since I wrote in C++.
and I've never done anything quiet this high level.
So basically I need to create a class.
The constructor for the class needs to take a reference (or pointer) to a method form another class, or to a function.
Basically I have a class that needs to on occasion read a value from a fltk valuator (version 1.1.x), and then change some stuff about itself.
Each object will have it's own valuator associated with it.
(they also have a link to another object of the same parent, which after updating them selves from the valuator will tell to update, and so on)
So how do i pass functions around, in constructors?
Here is an example where a method of Foo is passed to the Bar constructor and later invoked on a given Bar object:
struct Foo
{
int z;
int add(int x, int y)
{
return x + y + z;
}
int mul(int x, int y)
{
return x * y * z;
}
};
typedef int (Foo::*foo_method)(int, int);
struct Bar
{
foo_method m;
Bar(foo_method m) : m(m) {}
int call_on(Foo* foo)
{
return (foo->*m)(4, 2);
}
};
int main()
{
Bar bar(&Foo::add);
Foo foo = { 123 };
bar.call_on(&foo);
}
If, on the other hand, you already know the Foo object at Bar construction time, then Bar does not really care which class the method belongs to. All it needs is a functor to call later, and the Foo object can simply be bound by the client.
#include <functional>
struct Bar
{
std::function<int (int, int)> f;
Bar(std::function<int (int, int)> f) : f(f) {}
int call()
{
return f(4, 2);
}
};
using namespace std::placeholders;
int main()
{
Foo foo = { 123 };
Bar bar(std::bind(&Foo::add, &foo, _1, _2));
bar.call();
}
If you don't have a C++0x compiler, replace std::bind with std::tr1::bind or boost::bind.
Your constructor might look something like this:
// convenient typedef. This is for a pointer to a function in Foo
// The function returns void and takes no parameters.
typedef void (Foo::*FooPtr)();
class Bar {
public:
Bar (FooPtr foo_ptr);
};
Check out some web references for more details on the syntax for pointer-to-members. It's a lot easier if you get familiar with it first.
As an additional note, check out the functions mem_fun and mem_fun_ref. These may do what you need.
The easiest way to capture this is with boost::function. It can store function pointers, but also the result of binding a member function to an object.
For instance,
class Foo {
Foo(boost::function<int(void)>);
};
will allow you to accept any source of integers.
If I have a constructor with say 2 required parameters and 4 optional parameters, how can I avoid writing 16 constructors or even the 10 or so constructors I'd have to write if I used default parameters (which I don't like because it's poor self-documentation)? Are there any idioms or methods using templates I can use to make it less tedious? (And easier to maintain?)
You might be interested in the Named Parameter Idiom.
To summarize, create a class that holds the values you want to pass to your constructor(s). Add a method to set each of those values, and have each method do a return *this; at the end. Have a constructor in your class that takes a const reference to this new class. This can be used like so:
class Person;
class PersonOptions
{
friend class Person;
string name_;
int age_;
char gender_;
public:
PersonOptions() :
age_(0),
gender_('U')
{}
PersonOptions& name(const string& n) { name_ = n; return *this; }
PersonOptions& age(int a) { age_ = a; return *this; }
PersonOptions& gender(char g) { gender_ = g; return *this; }
};
class Person
{
string name_;
int age_;
char gender_;
public:
Person(const PersonOptions& opts) :
name_(opts.name_),
age_(opts.age_),
gender_(opts.gender_)
{}
};
Person p = PersonOptions().name("George").age(57).gender('M');
What if you made a parameter object that contained all the fields? Then you could just pass that, and just set whichever fields you need. There's probably a name for that pattern, not sure what it is though...
UPDATE:
Code might look like somewhat this:
paramObj.x=1;
paramObj.y=2;
paramObj.z=3;
paramObj.magic=true;
... //set many other "parameters here"
someObject myObject = new someObject(paramObj);
and inside the someObject constructor you can set defaults for things that were not already set (or raise an error if it was mandatory).
Honestly, I'm not a big fan of this solution, but I've used it once or twice when paramObj made sense by containing a set of data that usually all went together (so we could use it for more than just constructors), and it was better than multiple constructors. I found that it was ugly but it worked, YMMV.
And now for the "Boost has something for it" answer:
The Boost Parameter Library seems to be a good fit to your use case.
All new for C++17
#include <optional>
using optional_int = std::optional<int>;
class foo {
int arg0, arg1; // required
int arg2, arg3; // optional
const int default_2 = -2;
const int default_3 = -3;
public:
foo(int arg0, int arg1, optional_int opt0 = {}, optional_int opt1 = {})
: arg0(arg0), arg1(arg1)
, arg2(opt0.value_or(default_2))
, arg3(opt1.value_or(default_3))
{ }
};
int main() {
foo bar(42, 43, {}, 45); // Take default for opt0 (arg2)
return 0;
}
I have a cubic spline implementation that allows the user optionally to specify the first derivative at either the left end, the right end, or both. If a derivative is not specified, then the code in effect calculates one, by assuming that the second derivative is zero (the so-called "natural spline"). Here is a fragment for the left end.
// Calculate the second derivative at the left end point
if (!left_deriv.has_value()) {
ddy[0]=u[0]=0.0; // "Natural spline"
} else {
const real yP0 = left_deriv.value();
ddy[0] = -0.5;
u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yP0);
}