I could find a way to do Designated Initializers in C++0x with only one member initializing.
Is there a way for multiple member initializing ?
public struct Point3D
{
Point3D(float x,y) : X_(x) {}
float X;
};
I want :
public struct Point3D
{
Point3D(float x,y,z) : X_(x), Y_(y), Z_(z) {}
float X_,Y_,Z_;
};
You have a few mistakes in your constructor, here is how you should write it:
/* public */ struct Point3D
// ^^^^^^
// Remove this if you are writing native C++ code!
{
Point3D(float x, float y, float z) : X_(x), Y_(y), Z_(z) {}
// ^^^^^ ^^^^^
// You should specify a type for each argument individually
float X_;
float Y_;
float Z_;
};
Notice, that the public keyword in native C++ has a meaning which is different from the one you probably expect. Just remove that.
Moreover, initialization lists (what you mistakenly call "Designated Initializers") are not a new feature of C++11, they have always been present in C++.
#Andy explained how you should be doing this if you're going to define your own struct.
However, there is an alternative:
#include <tuple>
typedef std::tuple<float, float, float> Point3D;
and then define some function as:
//non-const version
float& x(Point3D & p) { return std::get<0>(p); }
float& y(Point3D & p) { return std::get<1>(p); }
float& z(Point3D & p) { return std::get<2>(p); }
//const-version
float const& x(Point3D const & p) { return std::get<0>(p); }
float const& y(Point3D const & p) { return std::get<1>(p); }
float const& z(Point3D const & p) { return std::get<2>(p); }
Done!
Now you would use it as:
Point3D p {1,2,3};
x(p) = 10; // changing the x component of p!
z(p) = 10; // changing the z component of p!
Means instead of p.x, you write x(p).
Hope that gives you some starting point as to how to reuse existing code.
Related
I have a namespace, Vector2, (inside another namespace, CHIM) which represents a 2D Vector. We use the zero vector ( [0, 0] ) multiple times, therefore, we would like to be able to write something like:
Vector2 a = CHIM::Vector2::ZERO;
Which is something commonly used in Unity's game engine.
The problem is, class Vector2 cannot [obviously] contain a member of its type, since it would have infinite size.
We currently solved this by making a static function that returns a Vector2 representing a zero vector. But this makes it such that the code has to run a function:
Vector2 a = CHIM::Vector2::ZERO();
As you can see, it's a bit more verbose, although the result is the same.
Is there any way to make this?
[EDIT]
Here's a simple example of what the code looks like:
#define CHIM_API
namespace CHIM {
union CHIM_API Vector2 {
struct { float x, y; };
struct { float u, v; };
struct { float w, h; };
struct { float width, height; };
float vec[2];
Vector2() : x(0), y(0) {};
Vector2(float x, float y) : x(x), y(y) {}
inline const static Vector2 ZERO = {0, 0}; // ERROR: Variable has incomplete type 'const Vector2'
// Rest of the code
}
Don't inline incomplete data types
namespace CHIM {
union Vector2 {
struct { float x, y; };
struct { float u, v; };
struct { float w, h; };
struct { float width, height; };
float vec[2];
Vector2() : x(0), y(0) {};
Vector2(float x, float y) : x(x), y(y) {}
const static Vector2 ZERO;
};
}
Define const CHIM::Vector2 CHIM::Vector2::ZERO; in .cpp.
See Static Members
However, if the declaration uses constexpr or inline (since C++17) specifier, the member must be declared to have complete type.
General question :
If there are two objects A and B with respective functions f_A(arg list) and f_B(arg list).
What's the best way to create an object C with a function compounded of f_A(...) and f_B(...) ?
for example : f_C() = f_A() + f_B() or f_C() = f_A(f_B())
Is it possible to overload the "+" operator such that we can create the object C doing something like that ?
auto object_c = object_a + object_b
Here is a sample of my code :
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
)
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
GaussianKernel operator+(const GaussianKernel& b) {
/*Here I would like to overload the + operator such that
I can create a kernel from two others kernels,
I mean with a covariance function compound of the previous ones
*/
}
private:
double m_sigma;
double m_scale;
};
Thanks you.
Given two methods f_A and f_B you can get f_C returning the sum of the others by using for example a lambda:
auto f_C = [](/*param*/){ return f_A(/*param*/) + f_B(/*param*/); };
auto sum_result = f_C(param);
To get the compound method it would be this:
auto f_C = [](/*param*/){ return f_B( f_A(/*param*/)); };
auto compound_result = f_C(param);
PS: I know that this is not directly applicable to your example, still trying to find out what exactly you want to do.
I would start with prototype solution like this:
class FooKernel : public Kernel {
public:
FooKernel (std::function<double(double, double)> fun) : fun_(fun) {}
double covarianceFunction(
double X,
double Y
) const {
return fun_(X, Y);
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
std::function<double(double, double)> fun_;
};
class GaussianKernel : public Kernel {
public:
GaussianKernel(double sigma) : m_sigma(sigma), m_scale(1) {}
double covarianceFunction(
double X,
double Y
) const
{
double result;
result = m_scale * exp(-norm(X - Y) / (m_sigma*m_sigma));
return result;
}
template<class T>
auto operator+(const T &b) const {
return FooKernel([b, this](double X, double Y){
return this->covarianceFunction(X, Y) + b.covarianceFunction(X, Y);
});
}
private:
double m_sigma;
double m_scale;
};
No longer lambdas are used, but now uses Your function as You wished.
Later on I would try to remove the std::function as it may have quite big performance impact. Instead I would make the FooKernel a class template, that stores callable by value.
I would suggest another subclass of Kernel:
class CompoundGaussianKernel : public Kernel {
public:
CompoundGaussianKernel(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
: m_kernel1(kernel1), m_kernel2(kernel2)
{}
double covarianceFunction(double X, double Y)
{
return m_kernel1.covarianceFunction(X, Y) + m_kernel2.covarianceFunction(X, Y);
// or any other composition than "+"
}
private:
GaussianKernel m_kernel1;
GaussianKernel m_kernel2;
};
I recommend not to define operator+ inside of a class but as a free function.
CompoundGaussianKernel operator+(GaussianKernel const& kernel1, GaussianKernel const& kernel2)
{
return CompoundGaussianKernel(kernel1, kernel2);
}
I need to create a functor with parameters and call it in an accessor - I'm hoping that the compiler will optimize away the code for speed. Here is my attempt:
struct X {
X(int a, float b) : _a(a), _b(b) {}
float operator()(float value) const { /* do something */; }
int _a;
float _b;
};
struct Y {
Y(const X&& x) : _x(move(x)) {}
float operator()(float value) const { return _x(value); }
const X&& _x;
};
which I call thus in an accessor of some Object of class Value:
float getValue() const {
X x(2, 3.14);
Y y(move(x));
return y(_value);
}
Is this the best way to code this, or can it be done in a simpler way?
Due to some legacy C code, I have the following POD struct defining 2D coordinates; and a C++ class inheriting from it in order to provide various operations:
struct coord
{
double x;
double y;
};
class CoordClass : public coord
{
// Contains functions like...
const CoordClass& operator+=(const CoordClass& rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
double Magnitude() const { return std::sqrt(x*x + y*y); }
};
At present, CoordClass defines a constructor:
CoordClass(double xx, double yy) { x = xx; y = yy; }
Given x and y are members of the POD base struct coord, is it possible to write that constructor as an initialiser list and empty body instead? Answers considering both C++03 and C++11 interest me.
In C++11 you can provide this constructor:
CoordClass(double x, double y) : coord{x, y} {}
In C++03 is also possible to get an empty constructor body but I don't think it's worth doing:
CoordClass(double x, double y) : coord(make_coord(x, y)) {}
where make_coord is:
coord make_coord(double x, double y) {
coord c = { x, y };
return c;
}
It can be a private static method of CoordClass. Alternatively, it can be a free function which is static and/or a member of an anonymous namespace of CoordClass.cpp.
In C++11, if you define a defaulted default constructor to a struct, it can still be a POD in C++11. (See Is this struct POD in C++11? )
struct coord
{
double x;
double y;
coord() = default;
coord(double xx, double yy) : x(xx), y(yy) {}
};
Now the CoordClass constructor becomes easy:
CoordClass(double x, double y) : coord(x, y) {}
Try the following
CoordClass(double xx, double yy) : coord { xx, yy } {}
I've got two classes: a template class, and a regular class that inherits from it:
template <int N> class Vector
{
float data[N];
//etc. (math, mostly)
};
class Vector3 : public Vector<3>
{
//Vector3-specific stuff, like the cross product
};
Now, I'd like to have x/y/z member variables in the child class (full members, not just getters - I want to be able to set them as well). But to make sure that all the (inherited) math works out, x would have to refer to the same memory as data[0], y to data[1], etc. Essentially, I want a union, but I can't declare one in the base class because I don't know the number of floats in the vector at that point.
So - can this be done? Is there some sort of preprocessor / typedef / template magic that will achieve what I'm looking for?
PS: I'm using g++ 4.6.0 with -std=c++0x, if that helps.
Edit: While references would give the syntax I'm looking for, the ideal solution wouldn't make the class any bigger (And references do - a lot! A Vector<3> is 12 bytes. A Vector3 with references is 40!).
How about:
class Vector3 : public Vector<3>
{
public:
// initialize the references...
Vector3() : x(data[0]), y(data[1]), z(data[2]){}
private:
float& x;
float& y;
float& z;
};
Of course, if you want them to occupy the same space, then that's a different story...
With a little template magic, you can do the following...
#include <iostream>
template <int N, typename UnionType = void*> struct Vector
{
union
{
float data[N];
UnionType field;
};
void set(int i, float f)
{
data[i] = f;
}
// in here, now work with data
void print()
{
for(int i = 0; i < N; ++i)
std::cout << i << ":" << data[i] << std::endl;
}
};
// Define a structure of three floats
struct Float3
{
float x;
float y;
float z;
};
struct Vector3 : public Vector<3, Float3>
{
};
int main(void)
{
Vector<2> v1;
v1.set(0, 0.1);
v1.set(1, 0.2);
v1.print();
Vector3 v2;
v2.field.x = 0.2;
v2.field.y = 0.3;
v2.field.z = 0.4;
v2.print();
}
EDIT: Having read the comment, I realise what I posted before was really no different, so a slight tweak to the previous iteration to provide direct access to the field (which is what I guess you are after) - I guess the difference between this and Rob's solution below is that you don't need all the specializations to implement all the logic again and again...
How about template specialization?
template <int N> class Vector
{
public:
float data[N];
};
template <>
class Vector<1>
{
public:
union {
float data[1];
struct {
float x;
};
};
};
template <>
class Vector<2>
{
public:
union {
float data[2];
struct {
float x, y;
};
};
};
template <>
class Vector<3>
{
public:
union {
float data[3];
struct {
float x, y, z;
};
};
};
class Vector3 : public Vector<3>
{
};
int main() {
Vector3 v3;
v3.x;
v3.data[1];
};
EDIT Okay, here is a different approach, but it introduces an extra identifier.
template <int N> class Data
{
public:
float data[N];
};
template <> class Data<3>
{
public:
union {
float data[3];
struct {
float x, y, z;
};
};
};
template <int N> class Vector
{
public:
Data<N> data;
float sum() { }
float average() {}
float mean() {}
};
class Vector3 : public Vector<3>
{
};
int main() {
Vector3 v3;
v3.data.x = 0; // Note the extra "data".
v3.data.y = v3.data.data[0];
};
Here's one possibility, cribbed from my answer to this question:
class Vector3 : public Vector<3>
{
public:
float &x, &y, &z;
Vector3() : x(data[0]), y(data[1]), z(data[2]) { }
};
This has some problems, like requiring you to define your own copy constructor, assignment operator etc.
You can make the following:
template <int N> struct Vector
{
float data[N];
//etc. (math, mostly)
};
struct Vector3_n : Vector<3>
{
//Vector3-specific stuff, like the cross product
};
struct Vector3_a
{
float x, y, z;
};
union Vector3
{
Vector3_n n;
Vector3_a a;
};
Now:
Vector3 v;
v.n.CrossWhatEver();
std::cout << v.a.x << v.a.y << v.a.z
You could try the anonymous union trick, but that is not standard nor very portable.
But note that with this kind of union it is just too easy to fall into undefined behaviour without even noticing. It will probably mostly work anyway, though.
I wrote a way a while back (that also allowed getters/setters), but it was such a non-portable garrish hack that YOU REALLY SHOULD NOT DO THIS. But, I thought I'd throw it out anyway. Basically, it uses a special type with 0 data for each member. Then, that type's member functions grab the this pointer, calculate the position of the parent Vector3, and then use the Vector3s members to access the data. This hack works more or less like a reference, but takes no additional memory, has no reseating issues, and I'm pretty sure this is undefined behavior, so it can cause nasal demons.
class Vector3 : public Vector<3>
{
public:
struct xwrap {
operator float() const;
float& operator=(float b);
float& operator=(const xwrap) {}
}x;
struct ywrap {
operator float() const;
float& operator=(float b);
float& operator=(const ywrap) {}
}y;
struct zwrap {
operator float() const;
float& operator=(float b);
float& operator=(const zwrap) {}
}z;
//Vector3-specific stuff, like the cross product
};
#define parent(member) \
(*reinterpret_cast<Vector3*>(size_t(this)-offsetof(Vector3,member)))
Vector3::xwrap::operator float() const {
return parent(x)[0];
}
float& Vector3::xwrap::operator=(float b) {
return parent(x)[0] = b;
}
Vector3::ywrap::operator float() const {
return parent(y)[1];
}
float& Vector3::ywrap::operator=(float b) {
return parent(y)[1] = b;
}
Vector3::zwrap::operator float() const {
return parent(z)[2];
}
float& Vector3::zwrap::operator=(float b) {
return parent(z)[2] = b;
}
To finish off an old question: No. It makes me sad, but you can't do it.
You can get close. Things like:
Vector3.x() = 42;
or
Vector3.x(42);
or
Vector3.n.x = 42;
or even
Vector3.x = 42; //At the expense of almost quadrupling the size of Vector3!
are within reach (see the other answers - they're all very good). But my ideal
Vector3.x = 42; //In only 12 bytes...
just isn't doable. Not if you want to inherit all your functions from the base class.
In the end, the code in question ended up getting tweaked quite a bit - it's now strictly 4-member vectors (x, y, z, w), uses SSE for vector math, and has multiple geometry classes (Point, Vector, Scale, etc.), so inheriting core functions is no longer an option for type-correctness reasons. So it goes.
Hope this saves someone else a few days of frustrated searching!