Say I have a struct with a bunch of members:
struct foo {
int len;
bar *stuff;
};
As it so happens stuff will point to an array of bars that is len long. I'd like to encode this in stuff's type. So something like:
struct foo {
int len;
DependentLength<bar, &foo::len> stuff;
};
Then I could implement DependentLength to behave like a pointer to a bar array but that asserts when trying to looking at an index bigger than foo::len. However, I can't implement DependentLength<&foo::len>::operator[] because operator[] only takes one parameter, the index, and it needs to know the location of the 'foo' object in order to dereference the member pointer template parameter and do the assert check.
However, I happen to know that DependentLength will only ever be used here as a member of 'foo'. What I'd really like to do is tell DependentLength where to find len relative to itself, rather than relative to a foo pointer. So something like DependentLength<(char*)&foo::stuff - (char*)&foo::len> stuff;, but that's not legal C++. Is there a good or failing that evil language hack that could make this work?
So something like DependentLength<(char*)&foo::stuff - (char*)&foo::len> stuff;
You're asking templates to perform calculations based on dynamic properties passed to them during run-time ... that won't work for templates since they must be instantiated with values that allow the compile to create the code requested by the template parameters at compile time. Thus any values passed to a template must be resolvable at compile-time, and not run-time.
You're going to have to use a dynamic container type. For instance, std::vector meets your request where the std::vector::at() function will throw an exception if you exceed the bounds of the underlying container. It's unfortunately not as convenient as a static_assert, but again, using static_assert is impossible for this situation since you need run-time checking for the bounds. Additionally, std::vector also incorporates an overload for operator[], iterators, queries for it's size, etc.
You can tell the template the offset of the member to use as length.
template<typename T, typename LEN_T, ptrdiff_t LEN_OFFSET>
class DependentArray
{
public:
T& operator[](LEN_T i_offset)
{
if (i_offset < 0) throw xxx;
if (i_offset > this->size()) throw xxx;
return this->m_pArr[i_offset];
} // []
private:
LEN_T& size()
{
return *reinterpret_cast<LEN_T*>(reinterpret_cast<char*>(this) + LEN_OFFSET);
} // ()
private:
T* m_pArr;
};
struct foo
{
int len;
DependentArray<bar, int, -sizeof(int)> stuff;
};
Edit 2:
Thought of another solution. Use a class that is good for foo only to supply the offset of the size field and define its method after foo is defined and offsets can be calculated:
#define MEMBER_OFFSET(T,M) \
(reinterpret_cast<char*>(&reinterpret_cast<T*>(0x10)->M) - \
reinterpret_cast<char*>(reinterpret_cast<T*>(0x10)))
template<typename T, typename LEN_T, typename SIZE_OFFSET_SUPPLIER>
class FooDependentArray
{
public:
T& operator[](LEN_T i_offset)
{
if (i_offset < 0) throw xxx;
if (i_offset > this->size()) throw xxx;
return this->m_pArr[i_offset];
} // []
private:
LEN_T& size()
{
const ptrdiff_t len_offest = SIZE_OFFSET_SUPPLIER::getOffset();
return *reinterpret_cast<LEN_T*>(reinterpret_cast<char*>(this) + len_offset);
} // ()
private:
T* m_pArr;
};
struct FooSizeOffsetSupplier
{
static ptrdiff_t getOffset();
};
struct foo
{
int len;
DependentArray<bar, int, FooSizeOffsetSupplier> stuff;
};
ptrdiff_t FooSizeOffsetSupplier::getOffset()
{
return MEMBER_OFFSET(Foo,m_len) - MEMBER_OFFSET(Foo,m_pArr);
} // ()
This makes it possible to add and remove members from foo.
Related
Updates in bold
I am writing a hash function for a table of function pointers with the limitation that the structure of the function pointers and function table cannot be modified (i.e. they have been published to third-parties). Based on Can std::hash be used to hash function pointers?, std::hash can be used for function pointers. Adopting that, it yields the following solution.
The tedious part about this solution is that every time we add new APIs to FuncPointers struct, we'd have to modify the hash specialization to add the corresponding change (i.e. hashFunc(hashedValue, pFuncs->func3) ).
I am wondering if there's a better way to implement this hashing of function pointers so continuous modification to the hash specialization can be avoided?
typedef void (*func_type1) (int);
typedef void (*func_type2) (double);
typedef struct FuncPointers
{
func_type1 func1;
func_type2 func2;
...
} FuncPointers;
template <typename T> void hashFunc (size_t & HashedValue, T funcPointer)
{
std::hash<T> hash;
HashedValue ^= hash(funcPointer); // the XOR operator is randomly picked
}
namespace std
{
template<> struct hash<FuncPointers>
{
size_t operator()(FuncPointers *pFuncs)
{
size_t hashedValue = 0;
hashFunc(hashedValue, pFuncs->func1);
hashFunc(hashedValue, pFuncs->func2);
...
return hashedValue;
}
};
}
Start with this: https://stackoverflow.com/a/7115547/1774667
It provides a hash_tuple::hash<Tuple> that is a valid decent quality hasher (with combining and recursion support!) for a std::tuple.
Next, change FuncPointers as follows:
struct FuncPointers:std::tuple<func_type1, func_type2 /*, ...*/> {
// optional:
func_type1 func1() const { return std::get<0>(*this); }
func_type1& func1() { return std::get<0>(*this); }
//...
};
namespace std {
template<>
struct hash<FuncPointers> {
template<typename... Ts>
std::size_t operator()( std::tuple<Ts...> const& funcs ) const {
return hash_tuple::hash<std::tuple<Ts...>>{}(funcs);
}
};
}
which redirects your std::hash<FuncPointers> to invoke hash_tuple::hash<std::tuple<...>> on the parent of FuncPointers. If you do not want to inherit from std::tuple, changing it to a has-a instead of an is-a relationship should be easy.
The optional func() accessors give you closer to the old interface (just requires a () added), but also adds boilerplate.
An alternative would be:
template<unsigned N>
auto func() const->decltype( std::get<N>(*this) ){ return std::get<N>(*this); }
template<unsigned N>
auto& func()->decltype( std::get<N>(*this) ){ return std::get<N>(*this); }
which changes funcPointers.func1 to funcPointers.func<1>(), but gets rid of tonnes of boilerplate when you add a new func, and stays pretty similar to the old interface of funcPointers.
If there is not much code that is using the old interface, using std::get<N>() makes some sense.
If your names are more descriptive than func1 and you only used that for the example, an enumeration of the function names can be used with std::get or func<X> above. If you go with func<X> you can even make it typesafe (force the use of the named functions).
You'd be better off making your FuncPointers a std::tuple<func_type1, func_type2>. Then see this answer on hashing.
BTW, typedef struct FuncPointers { } FuncPointers is a C-ism which has never been necessary in C++.
What I am needing can be done by storing this pointer of enclosing class into nested class for example this way:
class CEnclosing {
public:
class CNested : public CSomeGeneric {
public:
CNested(CEnclosing* e) : m_e(e) {}
virtual void operator=(int i) { m_e->SomeMethod(i); }
CEnclosing* m_e;
};
CNested nested;
CEnclosing() : nested(this) {}
virtual void SomeMethod(int i);
};
int main()
{
CEnclosing e;
e.nested = 123;
return 0;
}
This works well, but requires sizeof(void*) bytes of memory more for each nested member class. Exist effective and portable way to do this without need to store pointer to instance of CEnclosing in m_e?
As stated previously, C++ does not provide any way to do this. A nested class has no special way to find its enclosing class. The solution you already have is the recommended way.
If you have an advanced scenario, and if you are prepared to maintain non-portable code, and if the cost of storing an additional pointer is important enough to use a risky solution, then there is a way based on the C++ object model. With a number of provisos I won't go into, you can rely on the enclosing and nested classes being laid out in memory in a predictable order, and there being a fixed offset between the start of the enclosing and nested classes.
The code is something like:
CEnclosing e;
int offset = (char*)&e.nested - (char*)&e;
//... inside nested class
CEnclosing* pencl = (CEnclosing*)((char*)this - offset);
OTOH it's equally possible that the offsetof macro may just do it for you, but I haven't tried it.
If you really want to do this, read about trivially copyable and standard layout in the standard.
I believe the following could be portable; though it is not fool-proof. Specifically, it will not work across virtual inheritance.
Also, I would like to point that it is not safe, in that it will happily compile even if the member you pass does not correspond to the one you compute the offset with:
#include <iostream>
template <typename C, typename T>
std::ptrdiff_t offsetof_impl(T C::* ptr) {
C c; // only works for default constructible classes
T* t = &(c.*ptr);
return reinterpret_cast<char*>(&c) - reinterpret_cast<char*>(t);
}
template <typename C, typename T, T C::* Ptr>
std::ptrdiff_t offsetof() {
static std::ptrdiff_t const Offset = offsetof_impl(Ptr);
return Offset;
}
template <typename C, typename T, T C::* Ptr>
C& get_enclosing(T& t) {
return *reinterpret_cast<C*>(reinterpret_cast<char*>(&t)
+ offsetof<C, T, Ptr>());
}
// Demo
struct E { int i; int j; };
int main() {
E e = { 3, 4 };
//
// BEWARE: get_enclosing<E, int, &E::j>(e.i); compiles ERRONEOUSLY too.
// ^ != ^
//
E& ref = get_enclosing<E, int, &E::j>(e.j);
std::cout << (void const*)&e << " " << (void const*)&ref << "\n";
return 0;
}
Still, it does run on this simplistic example, which allowed me to find 2 bugs in my initial implementation (already). Handle with caution.
The clear and simple answer to your question is no, C++11 doesn't have any special feature to handle your scenario. But there is a trick in C++ to allow you to do this:
If CEnclosing didn't have a virtual function, a pointer to nested would have the same value as a pointer to the containing instance. That is:
(void*)&e == (void*)&e.nested
This is because the variable nested is the first in the class CEnclosing.
However, since you have a virtual function in CEnclosing class, then all you need to do is subtract the vtable size from &e.nested and you should have a pointer to e. Don't forget to cast correctly, though!
EDIT: As Stephane Rolland said, this is a dangerous solution and, honestly, I wouldn't use it, but this is the only way (or trick) I could think of to access the enclosing class from a nested class. Personally, I would probably try to redesign the relation between these two classes if I really want to optimise memory usage up to the level you mentioned.
How about using multiple inheritance like this:
class CNested {
public:
virtual void operator=(int i) { SomeMethod(i); }
virtual void SomeMethod(int i) = 0;
};
class CEnclosing: public CSomeGeneric, public CNested {
int nEncMember;
public:
CNested& nested;
CEnclosing() : nested(*this), nEncMember(456) {}
virtual void SomeMethod(int i) { std:cout << i + nEncMember; }
};
I've got a list of types which can be send over the network, take this example:
enum types {
E_T1,
E_T2,
E_T3,
E_T4
};
Now I have a list of classes which correspond to each of the types, let's say each is declared as class E_T1 {...}, class E_T2 {...}, etc.
They are not derived from a common base class and it's not possible to do so. Each of the classes has a verification method I need to invoke with the data send over the network. The client sends the data D and a id correspointing to the message type. I need to get hold of the object corresponding to the type. I can use C++0x features if needed.
What I've tried so far is using specialized templates for the types, holding a typedef for the object related to it. This was obviously a stupid idea as templates parameters need to be compile time constant so doing something along getType<data.id()>::type is not possible.
Then I tried using Boost.Variant to get a common returnable type like this (used mpl vector to iterate over the registered types at runntime for debbuging):
template <typename C>
struct getType() {
typedef C type;
}
typedef boost::mpl::vector<
getType<E_T1>,
getType<E_T2>,
getType<E_TX>...
> _types;
typedef boost::make_variant_over<_types>::type _type;
//use a map to store each type <-> id
boost::unorderd_map<types, _type> m;
m[E_T1] = getType<E_T1>();
m[data.id()]::type x; //<- access type, can now call x.validate(data)
The problem with this is that it's limited to 20 entries per variant per default. This can be overwritten but from what I understood the overhead per type should be considered and we are talking about a few thousand types here.
Also tried boost.any but it doesn't hold any type information so that's out of the question again. Has anyone any good ideas how this can be solved elegantly?
Looking for something where I don't have to write a 1k switch statement anytime I handle a type.
All types are nown at compile type, same goes for their corresponding IDs.
Id -> Type resolving needs to happen at runtime though.
Thanks in advance,
Robin.
External Polymorphism (*)
It's a widely known idiom, however it's widely used: I first encountered it in the shared_ptr implementation and it's been quite useful in my toolbox.
The idea is to actually create a base class for all those types. But not having them derive from it directly.
class Holder {
public:
virtual ~Holder() {}
virtual void verify(unsigned char const* bytes, size_t size) const = 0;
}; // class Holder
template <typename T>
class HolderT: public Holder {
public:
HolderT(): _t() {}
virtual void verify(unsigned char const* bytes, size_t size) const {
_t.verify();
}
private:
T _t;
}; // class HolderT
template <typename T>
std::unique_ptr<Holder> make_holder() {
return std::unique_ptr<Holder>(new HolderT<T>());
}
So, it's the classic strategy of adding a new level of indirection.
Now, you obviously do need a switch to move from value to class. Or perhaps... a map ?
using maker = std::unique_ptr<Holder> (&)();
using maker_map = std::unordered_map<types, maker>;
std::unique_ptr<Holder> select(types const E) {
static maker_map mm;
if (mm.empty()) {
mm.insert(std::make_pair(E_T1, make_holder<EC_T1>));
// ...
}
maker_map::const_iterator it = mm.find(E);
if (it == mm.end()) { return std::unique_ptr<Holder>(); }
return (*it->second)();
}
And now you can handle them polymorphically:
void verify(types const E, unsigned char const* bytes, size_t size) {
std::unique_ptr<Holder> holder = select(E);
if (not holder) { std::cerr << "Unknown type " << (int)E << "\n"; return; }
holder->verify(bytes, size);
}
Of course, you're welcome to make the strategy vary according to your needs. For example moving the map out of select so that you can register your types dynamically (like for plugins).
(*) At least that's the name I have for it, I would quite happy to find out it's already been named.
I'll assume you have a generic way of handling a message, such as for example an overloaded function:
void handle_message(const E_T1& msg);
void handle_message(const E_T2& msg);
//...
Now, you do not really need to get the object's type. All you need is a way to handle a message of that type, given the undecoded message.
So, I recommend you populate a map of factory functions:
std::unordered_map<types, std::function<void (unsigned char const* bytes, size_t size)> handlers;
handlers[E_E1] = [](unsigned char const* bytes, size_t size) { handle_message(E_T1(bytes, size)); };
// ...
Then, once you've decoded the type, you can use handlers[type](bytes, size) to decode and handle a message.
Try variadic templates and your already defined getType class:
enum types { T1_ID, T2_ID, .... };
class T1; class T2; class T3; ....
template <types t> struct getType;
template <> struct getType<T1_ID> { typedef T1 type; };
template <> struct getType<T2_ID> { typedef T2 type; };
...
And the operation verify:
template <types...>
struct type_operation;
template <types t1, types... rest>
struct type_operation<t1, rest...>
{
void verify(types t)
{
if (t == t1)
{
typename getType<t1>::type a;
a.verify(); // read from network and verify the rest of data....
}
else type_operation<rest...>::verify(t, data);
}
};
template <>
struct type_operation<>
{
void verify(types t)
{
ostringstream log; log << "not suppoted: " << t;
throw std::runtime_error(log.str()); //
}
};
Usage:
typedef type_operation<T1_ID, T2_ID, T3_ID, ,,.., TN_ID> type_mapping;
types id;
readFromNetwork(id);
type_mapping::verify(id);
template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () const {
return &(Enum::OfInt(i)); // warning: taking address of temporary
}
const Enum operator* () const {
return Enum::OfInt(i); // There is no problem with this one!
}
private:
int i;
};
I get this warning above. Currently I'm using this hack:
template <class Enum>
class EnumIterator {
public:
const Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
private:
int i;
Enum tmp;
};
But this is ugly because iterator serves as a missing container.
What is the proper way to iterate over range of values?
Update:
The iterator is specialized to a particular set objects which support named static constructor OfInt (code snippet updated).
Please do not nit-pick about the code I pasted, but just ask for clarification. I tried to extract a simple piece.
If you want to know T will be strong enum type (essentially an int packed into a class). There will be typedef EnumIterator < EnumX > Iterator; inside class EnumX.
Update 2:
consts added to indicate that members of strong enum class that will be accessed through -> do not change the returned temporary enum.
Updated the code with operator* which gives no problem.
Enum* operator-> () {
tmp = Enum::OfInt(i);
return &tmp;
}
The problem with this isn't that it's ugly, but that its not safe. What happens, for example in code like the following:
void f(EnumIterator it)
{
g(*it, *it);
}
Now g() ends up with two pointers, both of which point to the same internal temporary that was supposed to be an implementation detail of your iterator. If g() writes through one pointer, the other value changes, too. Ouch.
Your problem is, that this function is supposed to return a pointer, but you have no object to point to. No matter what, you will have to fix this.
I see two possibilities:
Since this thing seems to wrap an enum, and enumeration types have no members, that operator-> is useless anyway (it won't be instantiated unless called, and it cannot be called as this would result in a compile-time error) and can safely be omitted.
Store an object of the right type (something like Enum::enum_type) inside the iterator, and cast it to/from int only if you want to perform integer-like operations (e.g., increment) on it.
There are many kind of iterators.
On a vector for example, iterators are usually plain pointers:
template <class T>
class Iterator
{
public:
T* operator->() { return m_pointer; }
private:
T* m_pointer;
};
But this works because a vector is just an array, in fact.
On a doubly-linked list, it would be different, the list would be composed of nodes.
template <class T>
struct Node
{
Node* m_prev;
Node* m_next;
T m_value;
};
template <class T>
class Iterator
{
public:
T* operator->() { return m_node->m_value; }
private:
Node<T>* m_node;
};
Usually, you want you iterator to be as light as possible, because they are passed around by value, so a pointer into the underlying container makes sense.
You might want to add extra debugging capabilities:
possibility to invalidate the iterator
range checking possibility
container checking (ie, checking when comparing 2 iterators that they refer to the same container to begin with)
But those are niceties, and to begin with, this is a bit more complicated.
Note also Boost.Iterator which helps with the boiler-plate code.
EDIT: (update 1 and 2 grouped)
In your case, it's fine if your iterator is just an int, you don't need more. In fact for you strong enum you don't even need an iterator, you just need operator++ and operator-- :)
The point of having a reference to the container is usually to implement those ++ and -- operators. But from your element, just having an int (assuming it's large enough), and a way to get to the previous and next values is sufficient.
It would be easier though, if you had a static vector then you could simply reuse a vector iterator.
An iterator iterates on a specific container. The implementation depends on what kind of container it is. The pointer you return should point to a member of that container. You don't need to copy it, but you do need to keep track of what container you're iterating on, and where you're at (e.g. index for a vector) presumably initialized in the iterator's constructor. Or just use the STL.
What does OfInt return? It appears to be returning the wrong type in this case. It should be returning a T* instead it seems to be returning a T by value which you are then taking the address of. This may produce incorrect behavior since it will loose any update made through ->.
As there is no container I settled on merging iterator into my strong Enum.
I init raw int to -1 to support empty enums (limit == 0) and be able to use regular for loop with TryInc.
Here is the code:
template <uint limit>
class Enum {
public:
static const uint kLimit = limit;
Enum () : raw (-1) {
}
bool TryInc () {
if (raw+1 < kLimit) {
raw += 1;
return true;
}
return false;
}
uint GetRaw() const {
return raw;
}
void SetRaw (uint raw) {
this->raw = raw;
}
static Enum OfRaw (uint raw) {
return Enum (raw);
}
bool operator == (const Enum& other) const {
return this->raw == other.raw;
}
bool operator != (const Enum& other) const {
return this->raw != other.raw;
}
protected:
explicit Enum (uint raw) : raw (raw) {
}
private:
uint raw;
};
The usage:
class Color : public Enum <10> {
public:
static const Color red;
// constructors should be automatically forwarded ...
Color () : Enum<10> () {
}
private:
Color (uint raw) : Enum<10> (raw) {
}
};
const Color Color::red = Color(0);
int main() {
Color red = Color::red;
for (Color c; c.TryInc();) {
std::cout << c.GetRaw() << std::endl;
}
}
I have a template class like this:
template<T>
class MyClass
{
T* data;
}
Sometimes, I want to use the class with a constant type T as follows:
MyClass<const MyObject> mci;
but I want to modify the data using const_cast<MyObject*>data (it is not important why but MyClass is a reference count smart pointer class which keeps the reference count in the data itself. MyObject is derived from some type which contains the count.
The data should not be modified but the count must be modified by the smart pointer.).
Is there a way to remove const-ness from T? Fictional code:
const_cast<unconst T>(data)
?
The simplest way here would be to make the reference count mutable.
However, if you are interested in how it would work with the const_cast, then reimplementing boost's remove_const should be quite simple:
template <class T>
struct RemoveConst
{
typedef T type;
};
template <class T>
struct RemoveConst<const T>
{
typedef T type;
};
const_cast<typename RemoveConst<T>::type*>(t)->inc();
You have the answer. const_cast works in both directions:
char* a;
const char* b;
a = const_cast<char*>(b);
b = const_cast<const char*>(a); // not strictly necessarily, just here for illustration
As for you specific issue, have you considered the mutable keyword? It allows a member variable to be modified inside a const method.
class foo {
mutable int x;
public:
inc_when_const() const { ++x; }
dec_when_const() const { --x; }
};
Make the reference count mutable in the class managed by your intrusive pointer. This is entirely reasonable, and reflects "logical constness" exactly correctly -- i.e. changing the object's reference count does not reflect any change in the state of the object itself. In other words, the reference count isn't logically part of the object -- the object just happens to be a convenient place to store this semi-unrelated data.
If you can use Boost, the Type Traits library provides the remove_const metafunction that does that.
Here is my C++11 unconst function template.
If you use it, you are flirting with undefined behavior. You have been warned.
// on Ubuntu (and probably others) compile and test with
// g++ -std=c++11 test.c && ./a.out ; echo $?
template < class T > T & unconst ( T const & t ) {
return const_cast < T & > ( t ) ;
}
// demonstration of use
struct {
const int n = 4;
} s;
int main () {
unconst ( s.n ) = 5;
return s.n;
}