Probably I am not the first person finding out that std::exception_ptr could be used to implement an any type (performance considerations being put aside), as it is probably the only type in C++ that can hold anything. Googling did not, however, bring any result in this direction.
Does anybody know whether the following approach has been used anywhere for anything useful?
#include <exception>
#include <iostream>
struct WrongTypeError : std::exception { };
class Any {
public:
template <class T>
void set (T t) {
try { throw t; }
catch (...) { m_contained = std::current_exception(); }
}
template <class T>
T const & get () {
try { std::rethrow_exception (m_contained); }
catch (T const & t) { return t; }
catch (...) { throw WrongTypeError {}; }
}
private:
std::exception_ptr m_contained = nullptr;
};
int main () {
auto a = Any {};
a.set (7);
std::cout << a.get<int> () << std::endl;
a.set (std::string {"Wonderful weather today"});
std::cout << a.get<std::string> () << std::endl;
return 0;
}
as it is probably the only type in C++ that can hold anything.
I'm afraid this is not the case. boost::any can hold any type, and even copies (assume the type is copyable) it correctly as well. It is implemented (broadly speaking) using a base class and a templated child:
class any_base {
...
}
template <class T>
class any_holder : public any_base
{
private:
T m_data;
}
From this you can imagine that you can stuff any type into an any_holder (with the right interface), and then you can hold an any_holder by pointer to any_base. This technique is a type of type erasure; once we have an any_base pointer we are holding an object but don't know anything about the type. You could say this is total type erasure, something like std::function provides partial type erasure (and may use similar techniques under the hood, I'm not sure off the top of my head).
boost::any provides additional interface to support its usage of holding any type, and it probably provides better performance as throwing exceptions is crazy slow. Also, as I mentioned before, it correctly copies the underlying object, which is pretty cool. exception_ptr is a shared ownership pointer, so I believe it makes shallow copies instead.
Boost any website: http://www.boost.org/doc/libs/1_59_0/doc/html/any.html
It's being considered for the standard I believe: http://en.cppreference.com/w/cpp/experimental/any
It seems like the implementation is similar to boost but adds a small object optimization.
exception_ptr is quite a strange beast as far as I can tell, I've come across it before and googled it and there's surprisingly little information out there. I'm pretty sure however that it's magical, i.e. it cannot be implemented in userspace. I say this because when you throw it, the type seems to magically unerase itself, this isn't generally possible.
You are certainly the first person I have come across who has thought of it.
I'm definitely impressed by your lateral thinking skills :)
There is a problem with this approach however, (other than the obvious performance problem).
This stems from the fact that throw is permitted to make a copy of the object thrown.
Firstly this places a restriction on what you may store in your 'any' class, secondly it will have further performance implications and thirdly, each time you access your object, the compiler is not obliged to give you the same one. It's allowed to give you a copy. This means that at the very least you should only store immutable objects this way. (Note: when I say 'should' I really mean 'absolutely should not!') :)
You could get around this by crafting a class that allocates memory to store the object, records it's type and deletes it properly... But if you did that you'd be better off without the exception complication anyway.
In any case, this is what boost::any does under the covers.
Related
I created a vector that stores any type of value (int, bool, string, &, object,...). I can store stuff, but i have no idea how to get an specific element ([index]). EDIT: (without adding the type)
I haven't tried many things because i have no clue. The only tecnic i can think of is dynamic_cast, but since is a template makes no sense.
#include <vector>
#include <iostream>
struct slot {
virtual void print() = 0;
};
template<typename kind>
struct item : public slot {
kind value;
item(kind value) : value{ value } {};
void print()override { std::cout << value<<std::endl; }
};
class Bag {
std::vector<slot*> backpack;
public:
template<typename kind>
void append(kind stuff) {
backpack.push_back(new item<kind>(stuff));
}
void print_to_test() {
for (slot* it : backpack) { it->print(); }
}
//kind get()...How do i get an item value?
};
Bag bag;
bag.append(1);
bag.append(true);
bag.append("Hola");
bag.append(1232131);
void* a = nullptr;
bag.append(a);
bag.print_to_test();
//works fine, prints everything
//but can't get an specific value, like bag[index]
The dynamic cast will work. Note that it requires at least one virtual method - a destructor can be used if nothing else.
Yes, there isn't a way how can you reliably retrieve the value. C++ doesn't have a general object base as other languages nor any useful runtime reflection.
What you've implemented is known as type erasure and is actually used in e.g. std::function or std::any.
You should not use raw pointers and new for ownership. Use std::unique_ptr instead. Also since you only refer to the objects through the base class you need the virtual destructor. Otherwise, you won't be able to delete them correctly, again one more reason for std::unique_ptr as it deletes the pointer by itself.
If you want to get the value, what would you do with it? To quote Bjarne Stroustrup:
There is no useful universal class: a truly universal carries no semantics of its own.
Yes, you can store this value in std::any, but that's it, what would you want to do with it? Print it? Well, in that case it's no longer any but printable as in your example, so either use templates or virtual methods to express these traits in the types of the stored objects.
Consider using std::variant for known set of possible types and prefer std::any to owning void*. If you need the latter rethink your design choices first.
As others pointed out, dynamic_cast will work fine (as long as the caller knows what type is in the specific index) :
item<int>& someInt = dynamic_cast<item<int>&>(*bag.backpack[0]);
std::cout << "someInt: ";
someInt.print();
Note: You didn't provide accessor to backpack member, so I assumed it's public
Output:
someInt: 1
I have a limited set of very different types, from which I want to store instances in a single collection, specifically a map. To this end, I use the type erasure idiom, ie. I have a non-templated base class from which the templated, type specific class inherits:
struct concept
{
virtual std::unique_ptr<concept> copy() = 0; // example member function
};
template <typename T>
struct model : concept
{
T value;
std::unique_ptr<concept> copy() override { ... }
}
I then store unique_ptrs to concept in my map. To retrieve the value, I have a templated function which does a dynamic cast to the specified type.
template <typename T>
void get(concept& c, T& out) {
auto model = dynamic_cast<model<T>>(&c);
if (model == nullptr) throw "error, wrong type";
out = model->value;
}
What I don't like about this solution is, that specifying a wrong T is only detected at runtime. I'd really really like this to be done at compile time.
My options are as I see the following, but I don't think they can help here:
Using ad hoc polymorphism by specifying free functions with each type as an overload, or a template function, but I do not know where to store the result.
Using CRTP won't work, because then the base class would need to be templated.
Conceptually I would need a virtual function which takes an instance of a class where the result will be stored. However since my types are fundamentally different, this class would need to be templated, which does not work with virtual.
Anyways, I'm not even sure if this is logically possible, but I would be very glad if there was a way to do this.
For a limited set of types, your best option is variant. You can operate on a variant most easily by specifying what action you would take for every single variant, and then it can operate on a variant correctly. Something along these lines:
std::unordered_map<std::string, std::variant<Foo, Bar>> m;
m["a_foo"] = Foo{};
m["a_bar"] = Bar{};
for (auto& e : m) {
std::visit(overloaded([] (Foo&) { std::cerr << "a foo\n"; }
[] (Bar&) { std::cerr << "a bar\n"; },
e.second);
}
std::variant is c++17 but is often available in the experimental namespace beforehand, you can also use the version from boost. See here for the definition of overloaded: http://en.cppreference.com/w/cpp/utility/variant/visit (just a small utility the standard library unfortunately doesn't provide).
Of course, if you are expecting that a certain key maps to a particular type, and want to throw an error if it doesn't, well, there is no way to handle that at compile time still. But this does let you write visitors that do the thing you want for each type in the variant, similar to a virtual in a sense but without needing to actually have a common interface or base class.
You cannot do compile-time type checking for an erased type. That goes against the whole point of type erasure in the first place.
However, you can get an equivalent level of safety by providing an invariant guarantee that the erased type will match the expected type.
Obviously, wether that's feasible or not depends on your design at a higher level.
Here's an example:
class concept {
public:
virtual ~concept() {}
};
template<typename T>
struct model : public concept {
T value;
};
class Holder {
public:
template<typename T>
void addModel() {
map.emplace(std::type_index(typeid(T)), std::make_unique<model<T><());
}
template<typename T>
T getValue() {
auto found = types.find(std::type_index(typeid(T)));
if(found == types.end()) {
throw std::runtime_error("type not found");
}
// no need to dynamic cast here. The invariant is covering us.
return static_cast<model<T>*>(found->second.get())->value;
}
private:
// invariant: map[type] is always a model<type>
std::map<std::type_index, std::unique_ptr<concept>> types;
};
The strong encapsulation here provides a level of safety almost equivalent to a compile-time check, since map insertions are aggressively protected to maintain the invariant.
Again, this might not work with your design, but it's a way of handling that situation.
Your runtime check occurs at the point where you exit type erasure.
If you want to compile time check the operation, move it within the type erased boundaries, or export enough information to type erase later.
So enumerate the types, like std variant. Or enumerate the algorithms, like you did copy. You can even mix it, like a variant of various type erased sub-algorithms for the various kinds of type stored.
This does not support any algorithm on any type polymorphism; one of the two must be enumerated for things to resolve at compile time and not have a runtime check.
I'm trying to understand when is the right time to use some of the structures that come with boost and had a question regarding the use of boost::optional with a reference.
Suppose I have the following class, using boost::optional:
class MyClass {
public:
MyClass() {}
initialise(Helper& helper) {
this->helper = helper;
}
boost::optional<Helper&> getHelper() {
return helper;
}
private:
boost::optional<Helper&> helper;
}
Why would I use the above instead of:
class MyClass {
public:
MyClass() : helper(nullptr) {}
initialise(Helper& helper) {
this->helper = &helper;
}
Helper* getHelper() {
return helper;
}
private:
Helper* helper;
}
They both convey the same intent, i.e. that getHelper could return null, and the caller still needs to test if a helper was returned.
Should you only be using boost::optional if you need to know the difference between 'a value', nullptr and 'not a value'?
Compared to a raw pointer, an optional reference may suggest that (1) pointer arithmetic is not used, and (2) ownership of the referent is maintained elsewhere (so delete will clearly not be used with the variable).
Great question, and John Zwinck's answer above is right. However, some people (e.g., many on the standardization committee), doubt whether these reasons are enough to justify the existence of optional<T&>, when optional<T&> can have such confusing semantics. Consider what should happen when you assign to one of these guys. Should it re-seat the reference (i.e., make it point to a different object), or assign through the reference, like a real T& does? A case can be made for either, which would cause confusion and subtle bugs. Support for optional<T&> was removed from the proposal that recently got accepted into the C++14.
In short, if you want to make your code portable to C++14's std::optional, prefer T* over boost::optional<T&>.
First off, sorry for the title. I couldn't really condense what I'm trying to ask into one phrase :(
I was reading this post, and it somehow got me thinking on function pointers. Specifically, I was wondering why it's "bad" (or, at least, rarely seen) to pass class member functions as function parameters, and then use that pointer on an existing object within that function.
Let's assume I have a template class "Container", which stores a single variable of type T and provides a method to get a const reference to this variable.
template<class T>
class Container {
public:
Container(T anObject) {
m_data = anObject;
}
const T& getData() const {
return m_data;
}
private:
T m_data;
};
Now, I would like to be able to execute member functions of T on m_data, but I don't want to make getData() non-const because that would enable all kinds of other mischief with the returned reference. My solution is to add a new public function, modifyData(...), to Container, which takes a function pointer to a member function of T as a parameter and executes it on m_data; like so:
// ...
void modifyData( void(typename T::*funcptr)(void) ) {
(m_data.*fptr)();
}
// ...
As-is, this will crash and burn if T is a pointer. For testing, I just created a specialized template for Container<T*> to address this, but I'm sure there would be a more elegant way.
A very construed example shows that this seems to work as intended:
// example class to be used with Container
class Data {
public:
Data() {m_count = 0; }
void incrementCount() { m_count++; }
int getCount() const { return m_count; }
private:
int m_count;
};
// ... in main.cpp:
Data dat;
Container<Data*> DCont(dat);
std::cout << cl.getData()->getCount() << std::endl; // outputs 0
DCont.modifyData<Data>(&Data::incrementCount);
std::cout << cl.getData()->getCount() << std::endl; // outputs 1
// compiler catches this:
// DCont.modifyData<SomeOtherClass>(&Data::incrementCount);
// this probably does something bad:
// DCont.modifyData<SomeOtherClass>(&SomeOtherClass::someFunc);
Now, instinctively this just seems like a horribly twisted way of doing things, and I've never seen code that works like this. But my question is, is there a performance/security reason why something like this is bad, or is it something that's just considered bad practice? If it's "just" bad practice, then why is that?
Obvious limitations that I could think of are that something like
// DCont.modifyData(&SomeOtherClass::someFunc);
will probably crash at runtime, but I think that could be addressed by checking the type of U against T in incrementData(). Also, as it is, modifyData only accepts void (*)() functions, but this could probably be addressed with variadic templates.
This example is obviously very construed and not implemented so well, but I think (hope?) it's good enough to explain what I'm talking about.
Thanks!
EDIT: There seems to be some confusion as to what the question is. Basically, this is the scenario I'm talking about: You have a bunch of classes from some library that you're trying to store in the container, and another function that generates certain containers; Now, you want the user to be able to call existing member functions on the objects within these containers, but not to modify the actual objects (like when returning a non-const reference with the getter). An actual implementation would probably use some sort of variadic template to be useful, but I need to think that through some more before posting example code.
In short, I'd like to limit a user's access to container members to only member functions of that member. Is there an easier way of doing this, or does this way not work in the way I was intending?
I don't have any problem with your architecture - I don't see it as bad practice. To me it seems quite a laborious way to protect data and doesn't really help you much in that the user can use any void function to modify the contained data which isn;t really a contract on what can and can't be changed.
I think the reason this construct is so rarely seen is that your requirement and goals of the container class are unusual.
Are there any established patterns for checking class invariants in C++?
Ideally, the invariants would be automatically checked at the beginning and at the end of each public member function. As far as I know, C with classes provided special before and after member functions, but unfortunately, design by contract wasn't quite popular at the time and nobody except Bjarne used that feature, so he removed it.
Of course, manually inserting check_invariants() calls at the beginning and at the end of each public member function is tedious and error-prone. Since RAII is the weapon of choice to deal with exceptions, I came up with the following scheme of defining an invariance checker as the first local variable, and that invariance checker checks the invariants both at construction and destruction time:
template <typename T>
class invariants_checker
{
const T* p;
public:
invariants_checker(const T* p) : p(p)
{
p->check_invariants();
}
~invariants_checker()
{
p->check_invariants();
}
};
void Foo::bar()
{
// class invariants checked by construction of _
invariants_checker<Foo> _(this);
// ... mutate the object
// class invariants checked by destruction of _
}
Question #0: I suppose there is no way to declare an unnamed local variable? :)
We would still have to call check_invariants() manually at the end of the Foo constructor and at the beginning of the Foo destructor. However, many constructor bodies and destructor bodies are empty. In that case, could we use an invariants_checker as the last member?
#include <string>
#include <stdexcept>
class Foo
{
std::string str;
std::string::size_type cached_length;
invariants_checker<Foo> _;
public:
Foo(const std::string& str)
: str(str), cached_length(str.length()), _(this) {}
void check_invariants() const
{
if (str.length() != cached_length)
throw std::logic_error("wrong cached length");
}
// ...
};
Question #1: Is it valid to pass this to the invariants_checker constructor which immediately calls check_invariants via that pointer, even though the Foo object is still under construction?
Question #2: Do you see any other problems with this approach? Can you improve it?
Question #3: Is this approach new or well-known? Are there better solutions available?
Answer #0: You can have unnamed local variables, but you give up control over the life time of the object - and the whole point of the object is because you have a good idea when it goes out of scope. You can use
void Foo::bar()
{
invariants_checker<Foo>(this); // goes out of scope at the semicolon
new invariants_checker<Foo>(this); // the constructed object is never destructed
// ...
}
but neither is what you want.
Answer #1: No, I believe it's not valid. The object referenced by this is only fully constructed (and thus starts to exist) when the constructor finished. You're playing a dangerous game here.
Answer #2 & #3: This approach is not new, a simple google query for e.g. "check invariants C++ template" will yield a lot of hits on this topic. In particular, this solution can be improved further if you don't mind overloading the -> operator, like this:
template <typename T>
class invariants_checker {
public:
class ProxyObject {
public:
ProxyObject(T* x) : m(x) { m->check_invariants(); }
~ProxyObject() { m->check_invariants(); }
T* operator->() { return m; }
const T* operator->() const { return m; }
private:
T* m;
};
invariants_checker(T* x) : m(x) { }
ProxyObject operator->() { return m; }
const ProxyObject operator->() const { return m; }
private:
T* m;
};
The idea is that for the duration of a member function call, you create an anonymous proxy object which performs the check in its constructor and destructor. You can use the above template like this:
void f() {
Foo f;
invariants_checker<Foo> g( &f );
g->bar(); // this constructs and destructs the ProxyObject, which does the checking
}
Ideally, the invariants would be automatically checked at the beginning and at the end of each public member function
I think this is overkill; I instead check invariants judiciously. The data members of your class are private (right?), so only its member functions can change the data memebers and therefore invalidate invariants. So you can get away with checking an invariant just after a change to a data member that particiaptes in that invariant.
Question #0: I suppose there is no way to declare an unnamed local variable? :)
You can usually whip up something using macros and __LINE__, but if you just pick a strange enough name, it should already do, since you shouldn't have more than one (directly) in the same scope. This
class invariants_checker {};
template<class T>
class invariants_checker_impl : public invariants_checker {
public:
invariants_checker_impl(T* that) : that_(that) {that_->check_invariants();}
~invariants_checker_impl() {that_->check_invariants();}
private:
T* that_;
};
template<class T>
inline invariants_checker_impl<T> get_invariant_checker(T* that)
{return invariants_checker_impl<T>(that);}
#define CHECK_INVARIANTS const invariants_checker&
my_fancy_invariants_checker_object_ = get_invariant_checker(this)
works for me.
Question #1: Is it valid to pass this to the invariants_checker constructor which immediately calls check_invariants via that pointer, even though the Foo object is still under construction?
I'm not sure whether it invokes UB technical. In practice it would certainly be safe to do so - where it not for the fact that, in practice, a class member that has to be declared at a specific position in relation to other class members is going to be a problem sooner or later.
Question #2: Do you see any other problems with this approach? Can you improve it?
See #2. Take a moderately sized class, add half a decade of extending and bug-fixing by two dozen developers, and I consider the chances to mess this up at at least once at about 98%.
You can somewhat mitigate this by adding a shouting comment to the data member. Still.
Question #3: Is this approach new or well-known? Are there better solutions available?
I hadn't seen this approach, but given your description of before() and after() I immediately thought of the same solution.
I think Stroustrup had an article many (~15?) years ago, where he described a handle class overloading operator->() to return a proxy. This could then, in its ctor and dtor, perform before- and after-actions while being oblivious to the methods being invoked through it.
Edit: I see that Frerich has added an answer fleshing this out. Of course, unless your class already needs to be used through such a handle, this is a burden onto your class' users. (IOW: It won't work.)
#0: No, but things could be slightly better with a macro (if you're ok with that)
#1: No, but it depends. You cannot do anything that would cause this to be dereferenced in before the body (which yours would, but just before, so it could work). This means that you can store this, but not access fields or virtual functions. Calling check_invariants() is not ok if it's virtual. I think it would work for most implementations, but not guaranteed to work.
#2: I think it will be tedious, and not worth it. This have been my experience with invariant checking. I prefer unit tests.
#3: I've seen it. It seems like the right way to me if you're going to do it.
unit testing is better alternative that leads to smaller code with better performance
I clearly see the issue that your destructor is calling a function that will often throw, that's a no-no in C++ isn't it?