Auto-cast two 3rd party classes? - c++

I'm using two 3rd party libraries, which both implement their own 2D vector class. Unfortunately, I have to work with both of them, so is there anyway I can write some "friend" functions so that one can automatically be converted to the other when I try to use them in functions from the other library?

Auto-cast seems not to be possible. You could define global conversion function and call it explicitly. Could you post definition of that classes? May be some trick with inheritance will be possible.
Something like this, but it is not auto-cast:
class T1 {};
class T2 {};
class UnionType : public T1, public T2
{
public:
UnionType( const T1& val ) {} // real storing should be here
UnionType( const T2& val ) {} // real storing should be here
operator T1() { T1 t; return t; } // real conversion should be here
operator T2() { T2 t; return t; } // real conversion should be here
};
int main()
{
T1 t;
T2 t2 = UnionType(t);
return 0;
}

Conversion operators have to be member functions.
In situations like this, I have used a convert<X,Y> function template, with full specialisations or overloads for each pair of types that I want to "cast". In this case, you wouldn't need the template, just two overloads, one in each direction, because for a given X there's only ever one thing you convert it to.
Then it's rarely any trouble to switch between one and the other (the notable exception being when you're using template code which requires that one parameter type be convertible to another). You can easily see in the code the boundary between the two APIs, without introducing much noise.
The reason I've had this situation a lot is writing OS abstraction layers - the underlying OS has one set of objects or opaque handles for various OS concepts, and the API you're implementing has another. It's much nicer to just "convert" from one set of concepts to the other, without having ConvertHostMutexToGuestMutex, ConvertGuestMutexToHostMutex, ConvertHostSocketOptsToGuestSocketOpts etc. The disadvantage is the usual one with widespread overloading, that it's not necessarily obvious where the functions are actually defined.

One way would be to derive from those classes and provide conversion operators for one another. But then you have to use the derived class objects through out your code. Here is some sample code:
class ThirdParty1
{
public:
ThirdParty1(int x, int y) : m_x(x), m_y(y)
{
}
int getX() const { return m_x; }
int getY() const { return m_y; }
private:
int m_x;
int m_y;
};
class ThirdParty2
{
public:
ThirdParty2(int x, int y) : m_x(x), m_y(y)
{
}
int getX() const { return m_x; }
int getY() const { return m_y; }
private:
int m_x;
int m_y;
};
template<class Type, class AdaptedType>
class TP1Adaptor : public Type
{
public:
TP1Adaptor(int x, int y): Type(x,y)
{
}
operator AdaptedType()
{
return AdaptedType(getX(),getY());
}
};
typedef TP1Adaptor<ThirdParty1, ThirdParty2> First2D;
typedef TP1Adaptor<ThirdParty2, ThirdParty1> Second2D;
void f(ThirdParty1 tp)
{
}
void f1(ThirdParty2 tp)
{
}
int main()
{
First2D f(0,0);
f1(f);
return 0;
}

Related

C++ Can I overload the bracket [] operator to do different things if it on the LHS vs RHS of an assignment?

I am looking to accomplish the following:
int x, y, z;
foo[x] = y; acts like do_this(x,y);
z = foo[x]; acts like z = do_that(x)
I can accomplish the first with a Foo class and a Helper class, where the operator[] returns by value a Helper class constructed with x, and the operator= for the Helper class is defined to run do_this(this->x, y). Like below:
class Foo {
public:
Helper operator[](int x) {
return Helper(x);
}
};
class Helper {
public:
Helper(x) {
this->x = x;
}
void operator=(int y) {
do_this(this->x, y);
}
private:
int x;
};
What I can't figure out is how to accomplish (2). Is there a way to overload the operator[] so that it knows if it was used on the lhs vs the rhs?
Yes - give your Helper class a conversion function to int:
class Helper {
public:
Helper(x){
this->x = x;
}
Helper& operator= (int y) {
do_this(this->x, y);
return *this;
}
operator int() const {
return do_that(this->x);
}
private:
int x;
};
This will also allow other uses like product *= foo[x]; or func_taking_int(foo[x]), etc.
One potential catch is that some uses of auto or function templates would still just keep the type Helper, which might not be what's wanted - so users of Foo should still understand that this proxy sugar is going on. It could also be helpful to have some alternative syntax to explicitly get the int value for cases like that, in either Foo or Helper.
I'm not sure I've understood what you actually want to do, but you are might be able to use the const version of the operator[] vs. the non-const version. For example:
struct Foo {
Z operator [] (int x) const { // this last const is important
return do_that(x);
}
Helper operator [] (int x) {
// as you yourself have written.
}
};
There are more tips and tricks to this, for forwarding arguments perfectly (a.k.a "perfect forwarding",) for being "const correct", and many other small things, but the gist of it is the above.

C++ Overload index operator for more than one array/vector

I'm not an advanced programmer. How can I overload the [] operator for a class that has two (or more) array/vector type variables?
class X
{
protected:
std::vector<double> m_x, m_y;
public:
double& operator[](const short &i) { return ???; }
};
What should I use for ???, or how can I do it (maybe adding other definitions?) to be able to call either variable?
Additional question: will this allow other classes of type class derived : public X access m_x and m_y for writing?
UPDATE:
Thank you everyone who answered, but I'm afraid that if I draw the line then the answer to my first question is no, and to the second yes. The longer version implies either an extra struct, or class, or plain setters/getters, which I wanted to avoid by using a simple function for all.
As it stands, the current solution is a (temporary) reference to each variable, in each class to avoid the extra X:: typing (and keep code clear), since m_x would have existed, one way or another.
you can write just a function for this, like:
double &get(unsigned int whichVector, unsigned int index)
{
return (whichVector == 0 ? m_x[index] : m_y[index]);
}
or use operator():
struct A
{
std::vector<int> a1;
std::vector<int> a2;
int operator()(int vec, int index)
{
return (vec == 0 ? a1[index] : a2[index]);
}
};
A a;
auto var = a(0, 1);
but still, this is kinda strange :) probably you should just give a const ref outside, like:
const std::vector<double> &getX() const { return m_x; }
and second question: protected will be convert into private in public inheritance (child/derived will have access to these memebers)
Assuming you want m_x and m_y indexed against the same parameter and a single return value:
struct XGetter
{
double& x;
double& y;
};
XGetter operator[](const short &i) { return { m_x[i], m_y[i] }; }
And the const overload:
struct XGetterReadOnly
{
double x;
double y;
};
XGetterReadOnly operator[](const short &i) const { return { m_x[i], m_y[i] }; }
The compiler will make a good job of optimizing away the intermediate classes XGetter and XGetterReadOnly where appropriate which maybe hard to get your head round if you're a new to C++.
If using mixin doesn't make you uncomfortable you could use tag dispatching like:
#include <utility>
#include <vector>
#include <iostream>
template <size_t I>
struct IndexedVector {
std::vector<double> v;
IndexedVector():v(10){}
};
template <size_t I>
struct tag {
int i;
};
template <size_t S, class = std::make_index_sequence<S>>
struct MixinVector;
template <size_t S, size_t... Is>
struct MixinVector<S, std::index_sequence<Is...>>: IndexedVector<Is>... {
template <size_t I>
double &operator[](tag<I> i) {
return IndexedVector<I>::v[i.i];
}
};
int main() {
MixinVector<2> mv;
mv[tag<0>{0}] = 1.0;
std::cout << mv[tag<0>{0}] << std::endl;
}
To use std::index_sequence you need however compiler supporting c++14 (you could though implement it yourself in c++11). The approach is easily expandable to any number of vectors by simple MixinVector template parameter modification.
There are many broken things, either at conceptual and design level.
Are you able to point your finger simultaneously against two distinct things? No? That's why you cannot use one index to address two distinct vector retaining their distinction.
You can do many things: whatever way to "combine" two value int one is good
by a syntactic point of view:
return m_x[i]+m_y[x] or return sin(m_x[i])*cos(m_y[i]) or return whatever_complicated_expression_you_like_much
But what's the meaning of that? The point is WHY THERE ARE TWO VECTOR IN YOUR CLASS? What do you want them to represent? What do you mean (semantically) indexing them both?
Something I can do to keep their distinction is
auto operator[](int i) const
{ return std::make_pair(m_x[i],m_y[i]); }
so that you get a std::pair<double,double> whose fist and second members are m_x[i] and m_y[i] respectively.
Or ... you can return std::vector<double>{m_x[i],m_y[i]};
About your other question: Yes, inheriting as public makes the new class able to access the protected parts: that's what protected is for.
And yes, you cam R/W: public,protected and private are about visibility, not readability and writeability. That's what const is about.
But again: what does your class represent? without such information we cannot establish what make sense and what not.
Ok, stated your comment:
you need two different funcntions: one for read (double operator[](unsigned) const) and one for write (double& operator[](unsigned) const)
If you know vectors have a known length -say 200-, that you can code an idex transforamtion like i/1000 to identify the vector and i%1000 to get the index,so that 0..199 addres the first, 1000..1199 address the second 2000..2199 address the third... etc.
Or ... you can use an std::pair<unsigned,unsigend> as the index (like operator[](const std::pair<unsigned,unsigned>& i), using i.first to identify the vector, and i.second to index into it, and then call x[{1,10}], x[{3,30}] etc.
Or ... you can chain vetor together as
if(i<m_x.size()) return m_x[i]; i-=m_x:size();
if(i<m_y.size()) return m_y[i]; i-=m_y:size();
if(i<m_z.size()) return m_z[i]; i-=m_z:size();
...
so that you index them contiguously.
But you can get more algorithmic solution using an array of vectors instead of distinct vector variables
if you have std::array<std::vector<double>,N> m; instead of m_x, m_y and m_z the above code can be...
for(auto& v: m)
{
if(i<v.size()) return v[i];
i-=v.size();
}
You can return a struct has two double
struct A{
double& x;
double& y;
A(A& r) : x(r.x), y(r.y){}
A(double& x, double& y) : x(x), y(y){}
};
class X
{
protected:
std::vector<double> m_x, m_y;
public:
A operator[](const short &i) {
A result(m_x[i], m_y[i]);
return result;
}
};
Thank for editing to #marcinj

What is the lifetime of a C++ lambda expression?

(I have read What is the lifetime of lambda-derived implicit functors in C++? already and it does not answer this question.)
I understand that C++ lambda syntax is just sugar for making an instance of an anonymous class with a call operator and some state, and I understand the lifetime requirements of that state (decided by whether you capture by value of by reference.) But what is the lifetime of the lambda object itself? In the following example, is the std::function instance returned going to be useful?
std::function<int(int)> meta_add(int x) {
auto add = [x](int y) { return x + y; };
return add;
}
If it is, how does it work? This seems a bit too much magic to me - I can only imagine it working by std::function copying my whole instance, which could be very heavy depending on what I captured - in the past I've used std::function primarily with bare function pointers, and copying those is quick. It also seems problematic in light of std::function's type erasure.
The lifetime is exactly what it would be if you replaced your lambda with a hand-rolled functor:
struct lambda {
lambda(int x) : x(x) { }
int operator ()(int y) { return x + y; }
private:
int x;
};
std::function<int(int)> meta_add(int x) {
lambda add(x);
return add;
}
The object will be created, local to the meta_add function, then moved [in its entirty, including the value of x] into the return value, then the local instance will go out of scope and be destroyed as normal. But the object returned from the function will remain valid for as long as the std::function object that holds it does. How long that is obviously depends on the calling context.
It seems you're more confused about std::function than lambdas.
std::function uses a technique called type-erasure. Here's a quick fly by.
class Base
{
virtual ~Base() {}
virtual int call( float ) =0;
};
template< typename T>
class Eraser : public Base
{
public:
Eraser( T t ) : m_t(t) { }
virtual int call( float f ) override { return m_t(f); }
private:
T m_t;
};
class Erased
{
public:
template<typename T>
Erased( T t ) : m_erased( new Eraser<T>(t) ) { }
int do_call( float f )
{
return m_erased->call( f );
}
private:
Base* m_erased;
};
Why would you want to erase the type? Isn't the type we want just int (*)(float)?
What the type erasure allows is Erased can now store any value that is callable like int(float).
int boring( float f);
short interesting( double d );
struct Powerful
{
int operator() ( float );
};
Erased e_boring( &boring );
Erased e_interesting( &interesting );
Erased e_powerful( Powerful() );
Erased e_useful( []( float f ) { return 42; } );
This is:
[x](int y) { return x + y; };
Is equivalent to: (Or can be considered too)
struct MyLambda
{
MyLambda(int x): x(x) {}
int operator()(int y) const { return x + y; }
private:
int x;
};
So your object is returning an object that looks just like that. Which has a well defined copy constructor. So it seems very reasonable that it it can be correctly copied out of a function.
In the code that you posted:
std::function<int(int)> meta_add(int x) {
auto add = [x](int y) { return x + y; };
return add;
}
The std::function<int(int)> object that is returned by the function actually holds a moved instance of the lambda function object that was assigned to local variable add.
When you define a C++11 lambda that captures by-value or by-reference, the C++ compiler automatically generates a unique functional type, an instance of which is constructed when the lambda is called or assigned to a variable. To illustrate, your C++ compiler might generate the following class type for the lambda defined by [x](int y) { return x + y; }:
class __lambda_373s27a
{
int x;
public:
__lambda_373s27a(int x_)
: x(x_)
{
}
int operator()(int y) const {
return x + y;
}
};
Then, the meta_add function is essentially equivalent to:
std::function<int(int)> meta_add(int x) {
__lambda_373s27a add = __lambda_373s27a(x);
return add;
}
EDIT: By the way, I am not sure if you know this, but this is an example of function currying in C++11.

Deriving different and incomparable types from int in C++

I know I cannot derive from an int and it is not even necessary, that was just one (non)solution that came to my mind for the problem below.
I have a pair (foo,bar) both of which are represented internally by an int but I want the typeof(foo) to be incomparable with the typeof(bar). This is mainly to prevent me from passing (foo,bar) to a function that expects (bar, foo). If I understand it correctly, typedef will not do this as it is only an alias. What would be the easiest way to do this. If I were to create two different classes for foo and bar it would be tedious to explicitly provide all the operators supported by int. I want to avoid that.
As an alternative to writing it yourself, you can use BOOST_STRONG_TYPEDEF macro available in boost/strong_typedef.hpp header.
// macro used to implement a strong typedef. strong typedef
// guarentees that two types are distinguised even though the
// share the same underlying implementation. typedef does not create
// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D
// that operates as a type T.
So, e.g.
BOOST_STRONG_TYPEDEF(int, foo)
BOOST_STRONG_TYPEDEF(int, bar)
template <class Tag>
class Int
{
int i;
public:
Int(int i):i(i){} //implicit conversion from int
int value() const {return i;}
operator int() const {return i;} //implicit convertion to int
};
class foo_tag{};
class bar_tag{};
typedef Int<foo_tag> Foo;
typedef Int<bar_tag> Bar;
void f(Foo x, Bar y) {...}
int main()
{
Foo x = 4;
Bar y = 10;
f(x, y); // OK
f(y, x); // Error
}
You are correct, that you cannot do it with typedef. However, you can wrap them in a struct-enum pair or int encapsuled inside struct.
template<int N>
struct StrongType { // pseudo code
int i;
StrongType () {}
StrongType (const int i_) : i(i_) {}
operator int& () { return i; }
StrongType& operator = (const int i_) {
i = i_;
return *this;
}
//...
};
typedef StrongType<1> foo;
typedef StrontType<2> bar;
C++0x solution:
enum class foo {};
enum class bar {};

passing a class method as opposed to a function in std::sort

Within a class, I am trying to sort a vector, by passing a method of the same class. But it gives errors at the time of compilation. Can anyone tell what the problem is? Thank you!
it gives the following error:
argument of type bool (Sorter::)(D&, D&)' does not matchbool (Sorter::*)(D&, D&)'
I have also tried using sortBynumber(D const& d1, D const& d2)
#include<vector>
#include<stdio.h>
#include<iostream>
#include<algorithm>
class D {
public:
int getNumber();
D(int val);
~D(){};
private:
int num;
};
D::D(int val){
num = val;
};
int D::getNumber(){
return num;
};
class Sorter {
public:
void doSorting();
bool sortByNumber(D& d1, D& d2);
std::vector<D> vec_D;
Sorter();
~Sorter(){};
private:
int num;
};
Sorter::Sorter(){
int i;
for ( i = 0; i < 10; i++){
vec_D.push_back(D(i));
}
};
bool Sorter::sortByNumber(D& d1, D& d2){
return d1.getNumber() < d2.getNumber();
};
void Sorter::doSorting(){
std::sort(vec_D.begin(), vec_D.end(), this->sortByNumber);
};
int main(){
Sorter s;
s.doSorting();
std::cout << "\nPress RETURN to continue...";
std::cin.get();
return 0;
}
Make Sorter::sortByNumber static. Since it doesn't reference any object members, you won't need to change anything else.
class Sorter {
public:
static bool sortByNumber(const D& d1, const D& d2);
...
};
// Note out-of-class definition does not repeat static
bool Sorter::sortByNumber(const D& d1, const D& d2)
{
...
}
You should also use const references as sortByNumber should not be modifying the objects.
Unless you have a really good reason to do otherwise, just define operator< for the type of items you're sorting, and be done with it:
class D {
int val;
public:
D(int init) : val(init) {}
bool operator<(D const &other) { return val < other.val; }
};
class sorter {
std::vector<D> vec_D;
public:
void doSorting() { std::sort(vec_d.begin(), vec_D.end()); }
};
The way you're writing your sorter class depends on knowing a lot about the internals of the D class, to the point that they're practically a single class (e.g., it looks like neither can do much of anything without the other).
At a guess, your sorter may be a somewhat stripped-down version of your real code. The SortByNumber makes it sound like the original code might support a number of different kinds of keys, something like:
class D {
std::string name;
int height;
int weight;
// ...
};
and you'd want to be able to sort D objects by name, height, or weight. In a case like that, the comparisons are really still related to the D class, so I'd probably put them into a common namespace:
namespace D {
class D {
std::string name;
int height;
int weight;
public:
friend class byWeight;
friend class byHeight;
friend class byName;
// ...
};
struct byWeight {
bool operator()(D const &a, D const &b) {
return a.weight < b.weight;
}
};
struct byHeight {
bool operator()(D const &a, D const &b) {
return a.height < b.height;
}
};
struct byName {
bool operator()(D const &a, D const &b) {
return a.name < b.name;
}
};
}
Then sorting would look something like:
std::vector<D::D> vec_D;
// sort by height:
std::sort(vec_D.begin(), vec_D.end(), D::byHeight());
// sort by weight:
std::sort(vec_D.begin(), vec_D.end(), D::byWeight());
// sort by name:
std::sort(vec_D.begin(), vec_D.end(), D::byName());
Note that this does not use free functions. For this kind of purpose, a functor is generally preferable. I've also used a namespace to show the association between the object being sorted and the different ways of sorting it. You could make them nested classes instead, but I'd generally prefer the common namespace (keep coupling as loose as reasonable).
In any case, I would not give access to the raw data (even read-only access) via the object's public interface if it could be avoided (and in this case, it can be).
I see no reason for sortByNumber() to be a member function. When it's a member function it gains access to things it doesn't need (and therefore shouldn't have access to). Either extract the method and refactor it into a function object:
struct sortByNumber {
bool operator()(const D& d1, const D& d2) const {
return d1.getNumber() < d2.getNumber();
}
};
or make it a free function. Given the choice you should prefer a function object, because that makes it possible for the compiler to inline the code if it so chooses. Then, you can sort like so:
std::sort(vec_D.begin(), vec_D.end(), sortByNumber());
That said, you can get the code to compile as is like so, with boost::bind():
std::sort(vec_D.begin(), vec_D.end(),
boost::bind(&Sorter::sortByNumber, this, _1, _2));
You will need the boost libraries for that to work, and you will need to #include <boost/bind.hpp>.
I don't see any reason to make sortByNumber as a member function of class Sorter. You can do the sorting much more easily avoiding all the ugly bind code if you make it a free function. Also, you should use const wherever it is applicable in the code. Following is the example of doing it using free function:
First change the int getNumber() to const function as int getNumber() const;
Then write your free function sortByNumber again taking parameters by const reference.
bool sortByNumber(const D& d1, const D& d2);
You can call sort as :
std::sort(vec_D.begin(), vec_D.end(), sortByNumber);