I read about the builtin comparison operators. I wondered why there are no ordering operators(<, <=, >, >=) for member pointers. It is valid to compare the adresses of two members of an instantiation of a struct.
http://en.cppreference.com/w/cpp/language/operator_comparison:
3) If, within an object of non-union class type, two pointers point to different non-static data members with the same member access, or to subobjects or array elements of such members, recursively, the pointer to the later declared member compares greater. In other words, class members in each of the three member access modes are positioned in memory in order of declaration.
With the use of the adressof operator(&) and the member pointer dereference operator(.*) it is possible to compare the adresses, but an instance is needed.
My questions:
Why are there no builtin ordering operators for memberpointers?
How to compare two memberpointers without an instance?
My approach:
#include <iostream>
template<class S, class T>
int cmp_memberptr(T S::* a, T S::* b) {
//S s; // works, but needed instanciation
//S& s = std::declval<S>(); // error
S& s = *(S*)nullptr; // no instanciation, works (on my machine), but undefined behavior because of nullptr dereference (most compilers warn directly)!
// note: the precedence of .*:
return int(&(s.*a) < &(s.*b)) - int(&(s.*a) > &(s.*b));
};
struct Point { int x, y; };
int main(int argc, char const* const* argv) {
Point p;
#define tst(t) std::cout << #t " is " << ((t) ? "true" : "false") << '\n'
tst(&p.x < &p.y);
//tst(&Point::x < &Point::y); // the main problem!
tst(cmp_memberptr(&Point::x, &Point::y) < 0);
#undef tst
};
I considered the offsetof-macro, but it does not take memberpointers as parameters.
Member-pointers are more comlex beasts than you might think. They consist of an index into the potentially existing vtable and an offset (MSVC is broken in that regard without specifying extra options).
That is due to the existence of virtual inheritance, which means the exact offset of the virtual base sub-object depends on the most derived type, instead of the static type used for access.
Even the order of virtual bases depends on that.
So, you can create a total order for member-pointers pointing to elements of the same virtual base, or pointing to elements outside any virtual base. Any specific implementation might even mandate more (accepting the inefficiency that forces), but that's outside the purview of the standard.
In the end, you cannot rely on even having a total order without knowing implementation-details and having additional guarantees.
Example on coliru:
#include <iostream>
struct B {
int x;
};
struct M : virtual B {};
struct D : M {
int y;
};
static void print_offset(const M& m) {
std::cout << "offset of m.x: " << ((char*)&m.x - (char*)&m) << '\n';
}
int main() {
print_offset(M{});
print_offset(D{});
}
Example output:
offset of m.x: 8
offset of m.x: 12
I don't know how standards conformant this is, but according to Godbolt, the following code compiles cleanly in clang, gcc and MSVC and generates the right code (push 4, basically, for m2) in an efficient way:
#include "stdio.h"
template <typename T, typename M> int member_offset (M m)
{
const void *pv = nullptr;
const T *pT = static_cast <const T *> (pv);
return static_cast <int> (reinterpret_cast <const char *> (&(pT->*m)) - reinterpret_cast <const char *> (pT));
}
class x
{
public:
int m1;
int m2;
};
int main (void)
{
int m1_offset = member_offset <x> (&x::m1);
int m2_offset = member_offset <x> (&x::m2);
printf ("m1_offset=%d, m2_offset=%d\n", m1_offset, m2_offset);
}
Output from Wandbox:
Start
m1_offset=0, m2_offset=4
0
Finish
Now you can just use or compare member_offset's to do whatever you want.
EDIT
As pointed out by Caleth and Deduplicator above, this doesn't work with virtual inheritance. See my last comment to Deduplicator's answer for the reason why. As an aside, it's interesting to me that there is significant runtime overhead when accessing instance variables in the base class when using virtual inheritance. I hadn't realised that.
Also, the following simple macro is easier to use and works correctly with multiple inheritance with clang (so much for all those fancy templates):
#define member_offset(classname, member) \
((int) ((char *) &((classname*) nullptr)->member - (char *) nullptr))
You can test this with gcc and clang at Wandbox:
#include "stdio.h"
#define member_offset(classname, member) \
((int) ((char *) &((classname *) nullptr)->member - (char *) nullptr))
struct a { int m1; };
struct b { int m2; };
struct c : a, b { int m3; };
int main (void)
{
int m1_offset = member_offset (c, m1);
int m2 = member_offset (c, m2);
int m3 = member_offset (c, m3);
printf ("m1_offset=%d, m2=%d, m3=%d\n", m1_offset, m2, m3);
}
Output:
m1_offset=0, m2=4, m3=8
But if you use this macro with a class that uses virtual inheritance, you get a SEGFAULT (because the compiler needs to look inside the object to find the offset of that object's data members and there is no object there - just a nullptr).
So, the answer to the OP's question is that you do need an instance to do this in the general case. Maybe have a special constructor that does nothing to create one of these with minimal overhead.
SECOND EDIT
I thought about this some more, and it occurred to me that instead of saying:
int mo = member_offset (c, m);
You should instead say:
constexpr int mo = member_offset (c, m);
Then the compiler should alert you if class c is using virtual inheritance.
Unfortunately, neither clang nor gcc will compile this for any kind of class, virtual inheritance or not. MSVC, on the other hand, does, and only generates a compiler error if class c uses virtual inheritance.
I don't know which compiler is doing the right thing here, insofar as the standard goes, but MSVC's behaviour is obviously the most sensible.
Related
EDIT: thanks to the answers I was able to solve all the issues with my code. I post here the solution: it might be useful to somebody in the future. In particular, the suggestion of using a proxy class proved very useful! The example doens't consider all the cases but it should be trivial to add another type to the variant!
I am writing a C++ (C11 - Linux) custom class that sort of behaves like an unordered map {key, value}. I would like to overload the [] operator so that I can use the class with the same syntax as an unordered map: object[key] would return value.
The problem is that I need object[key] to return a variant type. I can store internally value as a string or struct but, when I retrieve it by using object[key], I need the returned value to be an int, float or string depending on some internal condition determined at runtime.
This is why I was thinking about using the boost::variant library ... but I am opened to any other suggestion. The only restriction is that the test class (in the example) have to compiled as a shared library .so and that the code must be C11 compatible (I mean compilable by GNU g++ 4.8.5).
I wrote a simple example to show what kind of behavior I would like The example is not meant to mean anything. It is just to illustrate the kind of error that I am getting. The real class that I am writing has a different structure but the usage of bool::variant and operator [] overload is the same.
test.cpp
#include <boost/variant.hpp>
typedef boost::variant<int, float> test_t;
class Test
{
int i ;
float f;
void set(int randomint, test_t tmp){
if ( randomint == 0 ) i = boost::get<int>(tmp);
else f = boost::get<float>(tmp);
}
test_t get(int randomint){
if ( randomint == 0 ) return i;
else return f;
}
struct IntOrFloat {
int randomint;
Test *proxy;
explicit operator int () const
{ return boost::get<int>(proxy->get(randomint)); }
void operator= (int tmp)
{ proxy->set(randomint, tmp); }
explicit operator float () const
{ return boost::get<float>(proxy->get(randomint)); }
void operator= (float tmp)
{ proxy->set(randomint, tmp); }
};
public:
IntOrFloat operator [](int randomint)
{ return IntOrFloat{randomint, this}; }
const IntOrFloat operator [](int randomint) const
{ return IntOrFloat{randomint, (Test *) this}; }
};
main.cpp
#include <iostream>
#include <boost/variant.hpp>
#include "test.cpp"
#define INTEGER 0
#define FLOAT 1
int main (void) {
Test test;
int i = 3;
float f = 3.14;
test[INTEGER] = i;
test[FLOAT] = f;
int x = (int) test[INTEGER];
float y = (float) test[FLOAT];
std::cout << x << std::endl;
std::cout << y << std::endl;
return 0;
}
To compile and run
g++ -fPIC -std=c++11 -shared -rdynamic -o test.so test.cpp
g++ -std=c++11 -o test main.cpp -Lpath/to/the/test.so -l:test.so
LD_LIBRARY_PATH="path/to/the/test.so" ./test
In C++, overload resolution does not happen on the return type, so given
int foo() { return 0; }
float foo() { return 0.f; }
there is no sanctioned way for the compiler to differentiate
int x = foo();
float f = foo();
. There is a trick using conversion operator overloads:
#include <iostream>
struct IntOrFloat {
operator int () const {
std::cout << "returning int\n";
return 0;
}
operator float () const {
std::cout << "returning float\n";
return 0.f;
}
};
IntOrFloat foo() { return IntOrFloat(); }
int main () {
int x = foo();
float f = foo();
}
You can force more verbosity by making the conversion explicit:
explicit operator int () const ...
explicit operator float () const ...
int x = static_cast<int>(foo());
int x = float(foo()); // old-style-cast
This proxy (or other conversion operator tricks) are as far as you'll to simulate return type overload resolution.
The idea once arised while searching a solution to supporting <euclidian vector> * <euclidian vector>-syntax, i.e. an operator* which either means dot product or vector product, depending on the type of the variable the product is assigned to.
In the end, it was not really practical and did not contribute positively to readability. The more verbose forms dot(vec, vec) and cross(vec, vec) were superior for several reasons, among which:
principle of least surprise: the computer graphics community is used to the terms "dot" and "cross"
less cryptic error messages: because this proxy technique is not idiomatic in C++, people are not used to the kind of error messages this temporal indirection yields
temporal and/or spatial locality: you are essentially returning a closure with code in it, which can be executed many times at many places. this can be doubly bad as it does not (actually, does) work well with auto & kind of declarations:
int main () {
const auto &f = foo();
const int g = f;
const int h = f;
std::cout << (int)f << "\n";
}
This prints something multiple times, going hand in hand with the least surprise principle. Of course this becomes less severe if your proxy basically just forwards readily available values. But the error messages won't become any better!
Note you can also incorporate template conversion operator overloads and wild metaprogramming. While worth a fun experiment, this is not something I'd love to put into a production code base, for maintenance and readability will even decrease.
What remains? Infinite possibilities; but some of the most feasible:
Variant datatypes
Tuple datatypes (look into std::tuple, which comes with conversion operators in case of distinct member types)
Different idioms (e.g. named methods instead of operator method)
Different algorithms
Different data structures
Different design patterns
When you use return i, what's happening underneath the hood is the creation of a temporary of type test_t that encapsulates that int value. This works fine in the function test::test_variant because the return type is test_t. This cannot work in the function test::operator[] because the return type is test_t&. The language prohibits creating a modifiable (l-value) reference to a temporary.
One way to make this work is to add a data member of type test_t to your class, with your test function operator[] setting this member and returning it rather than returning a temporary. Your real class will most likely do something different.
I'm trying to implement a minheap in C++. However the following code keeps eliciting errors such as :
heap.cpp:24:4: error: cannot convert 'complex int' to 'int' in assignment
l=2i;
^
heap.cpp:25:4: error: cannot convert 'complex int' to 'int' in assignment
r=2i+1;
^
heap.cpp: In member function 'int Heap::main()':
heap.cpp:47:16: error: no matching function for call to 'Heap::heapify(int [11], int&)'
heapify(a,i);
^
heap.cpp:47:16: note: candidate is:
heap.cpp:21:5: note: int Heap::heapify(int)
int heapify(int i) //i is the parent index, a[] is the heap array
^
heap.cpp:21:5: note: candidate expects 1 argument, 2 provided
make: * [heap] Error 1
#include <iostream>
using namespace std;
#define HEAPSIZE 10
class Heap
{
int a[HEAPSIZE+1];
Heap()
{
for (j=1;j<(HEAPISZE+1);j++)
{
cin>>a[j];
cout<<"\n";
}
}
int heapify(int i) //i is the parent index, a[] is the heap array
{
int l,r,smallest,temp;
l=2i;
r=2i+1;
if (l<11 && a[l]<a[i])
smallest=l;
else
smallest=i;
if (r<11 && a[r]<a[smallest])
smallest=r;
if (smallest != i)
{
temp = a[smallest];
a[smallest] = a[i];
a[i]=temp;
heapify(smallest);
}
}
int main()
{
int i;
for (i=1;i<=HEAPSIZE;i++)
{
heapify(a,i);
}
}
}
Ultimately, the problem with this code is that it was written by someone who skipped chapters 1, 2 and 3 of "C++ for Beginners". Lets start with some basics.
#include <iostream>
using namespace std;
#define HEAPSIZE 10
Here, we have included the C++ header for I/O (input output). A fine start. Then, we have issued a directive that says "Put everything that is in namespace std into the global namespace". This saves you some typing, but means that all of the thousands of things that were carefully compartmentalized into std:: can now conflict with names you want to use in your code. This is A Bad Thing(TM). Try to avoid doing it.
Then we went ahead and used a C-ism, a #define. There are times when you'll still need to do this in C++, but it's better to avoid it. We'll come back to this.
The next problem, at least in the code you posted, is a misunderstanding of the C++ class.
The 'C' language that C++ is based on has the concept of a struct for describing a collection of data items.
struct
{
int id;
char name[64];
double wage;
};
It's important to notice the syntax - the trailing ';'. This is because you can describe a struct and declare variables of it's type at the same time.
struct { int id; char name[64]; } earner, manager, ceo;
This declares a struct, which has no type name, and variables earner, manager and ceo of that type. The semicolon tells the compiler when we're done with this statement. Learning when you need a semicolon after a '}' takes a little while; usually you don't, but in struct/class definition you do.
C++ added lots of things to C, but one common misunderstanding is that struct and class are somehow radically different.
C++ originally extended the struct concept by allowing you to describe functions in the context of the struct and by allowing you to describe members/functions as private, protected or public, and allowing inheritance.
When you declare a struct, it defaults to public. A class is nothing more than a struct which starts out `private.
struct
{
int id;
char name[64];
double wage;
};
class
{
public:
int id;
char name[64];
double wage;
};
The resulting definitions are both identical.
Your code does not have an access specifier, so everything in your Heap class is private. The first and most problematic issue this causes is: Nobody can call ANY of your functions, because they are private, they can only be called from other class members. That includes the constructor.
class Foo { Foo () {} };
int main()
{
Foo f;
return 0;
}
The above code will fail to compile, because main is not a member of Foo and thus cannot call anything private.
This brings us to another problem. In your code, as posted, main is a member of Foo. The entry point of a C++ program is main, not Foo::main or std::main or Foo::bar::herp::main. Just, good old int main(int argc, const char* argv[]) or int main().
In C, with structs, because C doesn't have member functions, you would never be in a case where you were using struct-members directly without prefixing that with a pointer or member reference, e.g. foo.id or ptr->wage. In C++, in a member function, member variables can be referenced just like local function variables or parameters. This can lead to some confusion:
class Foo
{
int a, b;
public:
void Set(int a, int b)
{
a = a; // Erh,
b = b; // wat???
}
};
There are many ways to work around this, but one of the most common is to prefix member variables with m_.
Your code runs afoul of this, apparently the original in C passed the array to heapify, and the array was in a local variable a. When you made a into a member, leaving the variable name exactly the same allowed you not to miss the fact that you no-longer need to pass it to the object (and indeed, your heapify member function no-longer takes an array as a pointer, leading to one of your compile errors).
The next problem we encounter, not directly part of your problem yet, is your function Heap(). Firstly, it is private - you used class and haven't said public yet. But secondly, you have missed the significance of this function.
In C++ every struct/class has an implied function of the same name as the definition. For class Heap that would be Heap(). This is the 'default constructor'. This is the function that will be executed any time someone creates an instance of Heap without any parameters.
That means it's going to be invoked when the compiler creates a short-term temporary Heap, or when you create a vector of Heap()s and allocate a new temporary.
These functions have one purpose: To prepare the storage the object occupies for usage. You should try and avoid as much other work as possible until later. Using std::cin to populate members in a constructor is one of the most awful things you can do.
We now have a basis to begin to write the outer-shell of the code in a fashion that will work.
The last change is the replacement of "HEAPSIZE" with a class enum. This is part of encapsulation. You could leave HEAPSIZE as a #define but you should expose it within your class so that external code doesn't have to rely on it but can instead say things like Heap::Size or heapInstance.size() etc.
#include <iostream>
#include <cstdint> // for size_t etc
#include <array> // C++11 encapsulation for arrays.
struct Heap // Because we want to start 'public' not 'private'.
{
enum { Size = 10 };
private:
std::array<int, Size> m_array; // meaningful names ftw.
public:
Heap() // default constructor, do as little as possible.
: m_array() // says 'call m_array()s default ctor'
{}
// Function to load values from an istream into this heap.
void read(std::istream& in)
{
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
}
return in;
}
void write(std::ostream& out)
{
for (size_t i = 0; i < Size; ++i)
{
if (i > 0)
out << ','; // separator
out << m_array[i];
}
}
int heapify(size_t index)
{
// implement your code here.
}
}; // <-- important.
int main(int argc, const char* argv[])
{
Heap myHeap; // << constructed but not populated.
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
myHead.write(std::cout);
return 0;
}
Lastly, we run into a simple, fundamental problem with your code. C++ does not have implicit multiplication. 2i is the number 2 with a suffix. It is not the same as 2 * i.
int l = 2 * i;
There is also a peculiarity with your code that suggests you are mixing between 0-based and 1-based implementation. Pick one and stick with it.
--- EDIT ---
Technically, this:
myHeap.load(std::cin); // read from cin
for (size_t i = 1; i < myHeap.Size; ++i)
{
myHeap.heapify(i);
}
is poor encapsulation. I wrote it this way to draw on the original code layout, but I want to point out that one reason for separating construction and initialization is that it allows initialization to be assured that everything is ready to go.
So, it would be more correct to move the heapify calls into the load function. After all, what better time to heapify than as we add new values, keeping the list in order the entire time.
for (size_t i = 0; i < Size; ++i)
{
in >> m_array[i];
heapify(i);
}
Now you've simplified your classes api, and users don't have to be aware of the internal machinery.
Heap myHeap;
myHeap.load(std::cin);
myHeap.write(std::cout);
my question is about how to template'ize the name of a class member that should be used.
Maybe a simplified & pseudo example:
/**
Does something with a specified member of every element in a List.
*/
template<membername MEMBER> // <-- How to define such thing?
void doSomething(std::vector<MyClass> all){
for( i=0; i < all.size(); i++)
all[i].MEMBER++; // e.g.; use all[i].MEMBER in same way
}
and
class MyClass{
public:
int aaa, bbb, ccc;
}
and the application:
main(){
vector<MyClass> all = ....
// applicate doSomething() to all aaa's
doSomething<aaa>(all); // or:
doSomething<MyClass::aaa>(all); // or:
doSomething<?????>(all);
}
How should the template definition looks like, that I can switch which member variable (aaa, bbb or ccc) of MyClass is accessed/modified in doSomething(.) ?
In my real world task all MEMBER are of same type, as above.
Thanks,
Tebas
Template parameters are restricted to types, integer constants, pointers/references to functions or objects with external linkage and member pointers -- but no identifiers.
But you could use a member pointer as template parameter:
template<int MyClass::* MemPtr>
void doSomething(std::vector<MyClass> & all) {
for( i=0; i < all.size(); i++)
(all[i].*MemPtr)++;
}
:
doSomething<&MyClass::aaa>(all);
Note that I changed the doSomething function to take a reference instead of accepting the vector by value.
sellibitze's solution is fine (though to be honest not very: see my edit), only it limits you to using only members of type int. A more general solution would be this (although the member is NOT a template parameter here)
#include <vector>
struct MyClass
{
int i;
char c;
};
template <class T>
void DoSomething(std::vector<MyClass>& all, T MyClass::* MemPtr)
{
for(std::vector<MyClass>::size_type i = 0; i < all.size(); ++i)
(all[i].*MemPtr)++;
}
int main()
{
std::vector<MyClass> all;
DoSomething(all, &MyClass::i);
DoSomething(all, &MyClass::c);
}
EDIT:
Also please note that it is not generally a good idea for a pointer to member to be a template parameter inasmuch as only such pointers that are known compile-time can be passed, that is you can't determine the pointer runtime and then pass it as a template param.
I would use lambdas to solve this problem. Something like this:
#include <vector> // vector
#include <algorithm> // for_each
#include <functional> // function
struct MyClass {
void func1() const { std::cout << __FUNCTION__ << std::endl; }
void func2() const { std::cout << __FUNCTION__ << std::endl; }
};
void doSomething(std::vector<MyClass> all, std::function<void (MyClass& m)> f)
{
std::for_each(all.begin(), all.end(), f);
}
int main()
{
std::vector<MyClass> all;
all.push_back(MyClass());
// apply various methods to each MyClass:
doSomething(all, [](MyClass& m) { m.func1(); });
doSomething(all, [](MyClass& m) { m.func2(); });
}
Of course in this case the function doSomething is unnecessary. I could just as simply call for_each directly on all.
I realize this question is a bit old, but none of the answers use the method I have developed, and I would like to share it.
First, in C++ we typically are discouraged from directly accessing member variables and encouraged to provide setters/getters to help enforce hiding of information.
Second, while C++ goes a long way towards eliminating use of macros, they can still accomplish a lot of things that are difficult (or near impossible) with templates and classes.
The following uses a macro to create typed setters & getters for fields in a container member within a class:
//
// Bit(n) -- sets 'n'th bit.
// Bit(0) == 0x1 (b0000001),
// Bit(1) == 0x2 (b0000010),
// Bit(2) == 0x4 (b0000100),
// Bit(3) == 0x8 (b0001000), etc.
//
#define Bit(n) (1 << (n))
//
// BitMask(n) -- creates mask consisting of 'n' bits.
// BitMask(0) == 0x0 (b00000000),
// BitMask(1) == 0x1 (b00000001),
// BitMask(2) == 0x3 (b00000011),
// BitMask(3) == 0x7 (b00000111), etc.
//
#define BitMask(n) (Bit(n) - 1)
//
// BitRange(n, m) -- creates mask consisting of bits between n & m, inclusive.
// BitRange(0, 3) == 0x0f (b00001111),
// BitRange(2, 5) == 0x3c (b00111100),
// BitRange(6, 1) == 0x7e (b01111110), etc.
//
//
#define BitRange(n,m) (BitMask(n) ^ BitMask(m))
#define namedBitField(name, container, start, end, EnumType) \
EnumType name() const \
{return \
(EnumType) \
((container & BitRange(start,end)) \
>> start); \
}; \
void name(EnumType v) {container |= (v << start);}; \
class myTest
{
public:
enum vSet1
{
a = 1,
b = 2,
};
private:
unsigned long holder;
public:
myTest() {};
namedBitField(set1, holder, 0, 3, vSet1);
namedBitField(set2, holder, 4, 5, vSet1);
};
myTest mt;
The namedBitField() macro takes the name for the getter/setter pair, the target container -- holder in this example, the bitfield start/end, and the EnumType that is to be used for values in the bitfield.
If I now use the setter/getter pairs named set1() & set2() in the above example, and attempt to pass POD (plain-old-data) numbers I will get a warning from the compiler.
mt.set1(22); // compiler warns here.
mt.set1();
mt.set2(myTest::vSet1::a); // no warnings.
mt.set2();
No, it is not a "typed bitfield", but it is the next best thing.
No, it is not quite as easy to use as defining bitfields in a struct, but this way you get strong typing via the setters/getters.
Now, you could define the bitfields in structs, make them private, and access them via setters/getters as well, but then the information about where the bits are located is separated from the setters/getters which logically are tied to that information, and as several responders above have pointed out, each C++ compiler can put the bits anywhere they want, so without looking at generated assembler -- or testing on hardware if you are brave -- you cannot be certain things are happening the way you want.
The way the setters/getters created by namedBitField() manipulate the bits in a well-defined order and guarantee bit-order within container, so you can now use the code cross-platform for accessing I/O registers.
Note: in my example I use 'name' as both setter and getter with compiler sorting it out based on use. Some may prefer 'get_name' and 'set_name'. YMMV.
Since the getters/setters are public, and as long as the things you are iterating all derive from the same base class, you can now iterate across the items in a vector -- as above -- and get type-safe getting/setting for the values used in the iteration.
Here's the code. Is it possible to make last line work?
#include<iostream>
using namespace std;
template <int X, int Y>
class Matrix
{
int matrix[X][Y];
int x,y;
public:
Matrix() : x(X), y(Y) {}
void print() { cout << "x: " << x << " y: " << y << endl; }
};
template < int a, int b, int c>
Matrix<a,c> Multiply (Matrix<a,b>, Matrix<b,c>)
{
Matrix<a,c> tmp;
return tmp;
}
int main()
{
Matrix<2,3> One;
One.print();
Matrix<3,5> Two;
(Multiply(One,Two)).print(); // this works perfect
Matrix Three=Multiply(One,Two); // !! THIS DOESNT WORK
return 0;
}
In C++11 you can use auto to do that:
auto Three=Multiply(One,Two);
In current C++ you cannot do this.
One way to avoid having to spell out the type's name is to move the code dealing with Three into a function template:
template< int a, int b >
void do_something_with_it(const Matrix<a,b>& One, const Matrix<a,b>& Two)
{
Matrix<a,b> Three = Multiply(One,Two);
// ...
}
int main()
{
Matrix<2,3> One;
One.print();
Matrix<3,5> Two;
do_something_with_it(One,Two);
return 0;
}
Edit: A few more notes to your code.
Be careful with using namespace std;, it can lead to very nasty surprises.
Unless you plan to have matrices with negative dimensions, using unsigned int or, even more appropriate, std::size_t would be better for the template arguments.
You shouldn't pass matrices per copy. Pass per const reference instead.
Multiply() could be spelled operator*, which would allow Matrix<2,3> Three = One * Two;
print should probably take the stream to print to as std::ostream&. And I'd prefer it to be a free function instead of a member function. I would contemplate overloading operator<< instead of naming it print.
This wont be possible in C++03 but C++0x offers auto.
auto Three=Multiply(One,Two);
No, when using a class template, you have to specify all template arguments explicitly.
If your compiler supports it, you can use auto from C++0x instead:
auto Three=Multiply(One,Two);
In g++, you can enable C++0x support using the -std=c++0x flag.
Templates are used at compilation time and are used to implement static polymorphism. This means you should know everything about your objects at the moment your code is being compiled.
Hence, here the compiler fails, because this would be too hard for it to know that Three should have (2,5) dimensions (at least at currently common standard).
If this is a question for "just-to-know", then OK, but in real code you should obviously use constructors to initialize matrix (and set it's dimensions).
I am trying to access member variables of a class without using object. please let me know how to go about.
class TestMem
{
int a;
int b;
public:
TestMem(){}
void TestMem1()
{
a = 10;
b = 20;
}
};
void (TestMem::*pMem)();
int main(int argc, char* argv[])
{
TestMem o1;
pMem = &(TestMem::TestMem1);
void *p = (void*)&pMem;
// How to access a & b member variables using variable p
getch();
return 0;
}
The "right" way to do this is by using the offsetof() macro from <stddef.h>. Unfortunately offsetof() has some fairly draconian restrictions in C++:
Because of the extended functionality of structs in C++, in this language, the use of offsetof is restricted to "POD [plain old data] types", which for classes, more or less corresponds to the C concept of struct (although non-derived classes with only public non-virtual member functions and with no constructor and/or destructor would also qualify as POD).
So if you make a and b public and get rid of TestMem's constructor, you can write something like this to access a:
C++ style:
#include <cstddef>
int vala = *reinterpret_cast<int *>(reinterpret_cast<char *>(&o1)
+ offsetof(TestMem, a));
C style:
#include <stddef.h>
int vala = *(int *) ((char *) &o1 + offsetof(TestMem, a));
Notice that you need to use &o1 here, not p, which is a function pointer. The address of TestMem::TestMem1 won't have any relation to the locations of a and b. Class methods don't reside in memory anywhere near class member variables.
The "wrong" way is to just guess at where a and b are in memory. Most likely they are at offsets 0 and 4 from the start of o1, respectively. So this code would work most of the time:
int vala = *(int *) ((char *) &o1 + 0);
int valb = *(int *) ((char *) &o1 + 4);
There are a lot of assumptions here. This assumes that ints are 4 bytes and that there's no padding between a and b. On the other hand it doesn't have any of the restrictions from above: a and b don't need to be public, you can have a constructor, whatever.
Simple answer: Don't do it.
There just can not be any situation where you can justify accessing like this. There just has to be a different solution.
I came up with a solution but it's dirty:
class TestMem
{
public:
int a;
int b;
TestMem(){}
void TestMem1()
{
a = 10;
b = 20;
}
};
void* offset(void* ptr, ...)
{
va_list ap;
va_start(ap, ptr); // get 1st argument's address
long i = va_arg(ap, long); // get next argument
va_end(ap);
return (char*)ptr + i;
}
void test()
{
TestMem t;
void* p = (TestMem*)&t;
t.a = 8;
t.b = 9;
printf("%i\n", *(int*)offset(p, &TestMem::a));
printf("%i\n", *(int*)offset(p, &TestMem::b));
}
I wanted to comment the answer provided by John Kugelman, being a new member didn't have enough reputation, hence posting it like an answer.
offsetof - is a C function used with structures where every member is a public, not sure whether we can refer the private variables as referred in the answer.
However the same can be achieved replacing the offsetof with a simple sizeof, ofcourse when we are sure of the type of the data members.
int vala = *reinterpret_cast<int *>(reinterpret_cast<char *>( ptr ) );
int valb = *reinterpret_cast<int *>(reinterpret_cast<char *>( ptr ) + sizeof ( int ) );
To my knowledge, you wouldn't be able to access.
By the time you have assigned p, it doesn't refer to o1 here and
p cannot replace pMem in (o1.*pMem)(), as p is not defined as function member to TestMem.
Short answer: You can't.
Long answer: You can, but it's highly implementation dependent.
If you dump the memory you find at *p you'll see, somewhere around there, what you're looking for - a and b. But you will very likely also see some other stuff. What that stuff is, what it means, how big it is (and by implication where a and b actually live) is implementation dependent.
There totally is a way. C++ has member pointers, pointers relative to an object. They are defined by prefixing T:: to the * on the pointer type, and used by using the ->* or .* member pointer access operators. So yeah, it looks horrible :).
class T {
int a, b;
public:
typedef int T::* T_mem_ptr_to_int;
static T_mem_ptr_to_int const a_ptr;
static T_mem_ptr_to_int const b_ptr;
};
T::T_mem_ptr_to_int const T::a_ptr = &T::a;
T::T_mem_ptr_to_int const T::b_ptr = &T::b;
int weird_add(T* left, T* right) {
return left->*T::a_ptr + right->*T::b_ptr;
}
This is used much more often for member function pointers, which look like Result (T::*ptr_name)(Arg1, Arg2, ...).