I have a vector of many boost::any
In this vector I need to perform some operations on std::vector and on the elements of type IContainer
class IContainer
{
public:
virtual ~IContainer(){}
virtual const boost::any operator[](std::string) const = 0;
};
class AContainer : public IContainer
{
std::vector<int> vect_;
std::string name_;
public:
AContainer() : vect_({0, 1, 2, 3, 4, 5}), name_("AContainer") {}
virtual const boost::any operator[](std::string key) const
{
if (key == "str")
return (name_);
if (key == "vect")
return (vect_);
return nullptr;
}
};
So I have done the following function (imo quite ugly) but who works correctly
m is const std::vector<boost::any>&
for (const auto & elem : m)
{
try
{
std::vector<int> v = boost::any_cast<std::vector<int>>(elem);
display(v);
}
catch(boost::bad_any_cast){}
try
{
std::vector<IContainer*> v = boost::any_cast<std::vector<IContainer*>>(elem);
display(v);
}
catch(boost::bad_any_cast){}
try
{
AContainer v(boost::any_cast<AContainer>(elem));
try
{
display(boost::any_cast<const std::vector<int>>(v["vect"]));
}
catch (boost::bad_any_cast){}
try
{
std::cout << boost::any_cast<const std::string>(v["str"]) << std::endl;
}
catch (boost::bad_any_cast){}
try
{
display(boost::any_cast<std::vector<int> >(v));
}
catch (boost::bad_any_cast) {}
}
catch(boost::bad_any_cast){}
}
I have tried to add many "try{}try{}catch{}" but it's not working
Do you have any solutions better than what I have done
Edit
I have tried the solutions of James Kanze, user1131467 and Praetorian
So the 3 are working nicely, but when I have calculate the time of execution, the answer of user1131467 is a bit faster than the other. I must now find a solution to store each types in a map to avoid all this if/else
I will also take a look at boost::variant
Using the pointer-form of any_cast is much cleaner, as it uses the nullability of pointers:
for (const auto & elem : m)
if (T1* p = any_cast<T1>(&elem))
{
do stuff with *p;
}
else if (T2* p = any_cast<T2>(&elem))
{
do stuff with *p;
}
else if (...)
{
...
}
This also has the advantage of doing the cast once per case.
You can create a function along the lines of:
template <typename T>
bool
isInstanceOf( boost::any const& object )
{
return boost::any_cast<T>( &object ) != nullptr;
}
and use it, with if's to check:
if ( isInstanceOf<std::vector<int>>( elem ) ) {
display( boost::any_cast<std::vector<int>>( elem ) );
} else if ( isInstanceOf<std::vector<IContainer*>>( elem) ) {
display( boost::any_cast<std::vector<IContainer*>>( elem) );
}
// ...
You could write your own wrapper around any_cast that swallows exceptions.
template<typename T>
bool nothrow_any_cast( boost::any& source, T& out )
{
try {
out = boost::any_cast<T>( source );
} catch ( boost::bad_any_cast const& ) {
return false;
}
return true;
}
And then use it as
std::vector<int> vect;
std::string str;
if( nothrow_any_cast(v["vect"], vect ) ) {
// succeeded
} else if( nothrow_any_cast(v["str"], str ) ) {
// succeeded
} ...
However, if you do this, you're default constructing all the types, and then assigning them; so even if it looks a little cleaner, it's debatable whether it is any better than what you already have.
You can put all of the statements in one try block:
try {
// do all your stuff
}
catch (boost::bad_any_cast) {}
You missed to add any instruction when entering your catch(...){} block. So when an exception is thrown you do not handle it at all.
An appropriate handling usually includes to trace the level of error and try to resolve the state of error (if possible).
Since in every branch you do catch the same exception you can aggregate all of them to one block:
try{ ... }
catch(boost::bad_any_cast) { ...}
Why not use the pointer alternative of boost::any_cast, it does not throw anything, it returns nullptr if the requested type does not match with the store type.
And if you get a pointer back, you can just write an overload for display, that takes any
pointer, checks it for being null and calls the actual display function if the pointer is not null.
template<typename T>
void display(T* p) { if ( p ) display(*p); }
With the template above, only display is called for the correct cast.
for ( const auto& elem : m ) {
display(boost::any_cast<int>(&elem));
display(boost::any_cast<my_type>(&elem));
....
}
None of the answeres go the simple way that is now in the standard.
If you use "std::any" then you can just use the "type()" function to get the typeid of the containing item.
Related
I would like to wrap C types into a CPP class for better memory handling. For instance the below code snippet shows roughly what I would like to do:
class TJCompressor
{
public:
TJCompressor()
: m_tjInstance(tjInitCompress())
{
if (m_tjInstance == nullptr)
throw std::runtime_error("Could not create a TJ compressor instance");
}
~TJInstance()
{
tjDestroy(m_tjInstance);
}
const tjhandle& operator()() const
{
return m_tjInstance;
}
private:
tjhandle m_tjInstance = nullptr;
};
However, now I need to access the actual tjhandle through operator()() and I would prefer to get rid of this.
TJCompressor compressor;
tjDecompressHeader3(decompressor(), ... ); // works as expected
tjDecompressHeader3(decompressor, ... ); // preferred way of doing it
I am pretty sure that this is achievable but I somehow can't find anything about how to do it.
What you want I think is a conversion operator .... something that looks like
operator const tjhandle & () const { return m_tjInstance; }
you will then be able to call your function as
tjDecompressHeader3(decompressor, ...)
More information can be found here:
https://en.cppreference.com/w/cpp/language/cast_operator
I have multiple functions that return a std::optional<T>. Here's an example for a made-up type MyType:
struct MyType {
// ...
}
std::optional<MyType> calculateOptional() {
// ... lengthy calculation
if (success) {
return MyType(/* etc */);
}
return std::nullopt;
}
Let's assume these functions are costly to run and I want to avoid calling them more than once.
When calling them I want to immediately test the optional, and if it does contain a value, I want to use it immediately and never again. In Swift, for example, I can use the standard if-let statement:
if let result = calculateOptional() {
// Use result var
}
I would like to replicate this test-and-unwrap behavior in C++, while keeping the code as clean as possible at the point of use. For example, the obvious simple solution (to me at least) would be:
if (auto result = calculateOptional()) {
MyType result_unwrapped = *result;
// Use result_unwrapped var
}
But you have to unwrap inside the if, or use *result everywhere, which you don't have to do with Swift.
My only solution so far that genuinely gets close to the look and feel of Swift is:
template<typename T> bool optionalTestUnwrap(std::optional<T> opt, T& value) {
if (!opt.has_value()) { return false; }
value = *opt;
return true;
}
#define ifopt(var, opt) if (typename decltype((opt))::value_type (var); optionalTestUnwrap((opt), (var)))
ifopt (result, calculateOptional()) {
// Use result var
}
...but I'm also not a big fan of the use of a macro to replace a normal if statement.
Personally, I would just do:
if (auto result = calculateOptional()) {
// use *result
}
with a second best of giving the optional an ugly name and making a nicer-named alias for it:
if (auto resultOpt = calculateOptional()) {
auto& result = *resultOpt;
// use result
}
I think this is good enough. It's a great use-case for intentionally shadowing an outer-scope name (i.e. naming both the optional and the inner alias result), but I don't think we need to go crazy here. Even using *result isn't a big problem - the type system will likely catch all misuses.
If we really want to go in on Swift, the macro you're using requires default construction - and it's not really necessary. We can do a little bit better with (ideally __opt is replaced by a mechanism that selects a unique name, e.g. concatenating with __LINE__):
#define if_let(name, expr) \
if (auto __opt = expr) \
if (auto& name = *__opt; false) {} else
As in:
if_let(result, calculateOptional()) {
// use result
} else {
// we didn't get a result
}
This doesn't have any extra overhead or requirements. But it's kind of ridiculous, has its own problems, and doesn't seem worthwhile. But if we're just having fun, this works.
Another simple and potentially safer one:
#define unwrap(x, val, block) if (auto opt_##x = val) { auto &x = opt_##x; block }
Usage:
unwrap(result, calculateOptional(), {
// use result
});
You could wrap the optional in an own type with implicit conversion to the type and explicit to bool. Sorry I haven't tested this so far but I think it should work.
template<class T>
struct opt {
std::optional<T> _optional; // public so it stays an aggregate, probably writing constructors is better
explicit bool() const {
return _optional.has_value();
}
T&() {
return *_optional;
}
const T&() const {
return *_optional;
}
T&&() && { // Let's be fancy
return std::move(*optional);
}
}
opt<int> blub(bool val) {
return val ? opt<int>{0} : opt<int>{std::nullopt};
}
int main() {
if(auto x = blub(val)) { // I hope this works as I think it does
int y = x+1;
}
}
If calculateOptional() returns a std::pair<bool sucess, T result> or can be converted in one, you can use the following construct:
if (auto [s, result] = calculatePair(); s) {
} else {
}
or you use exceptions; (...) catches all exceptions
try {
auto result = calculate();
} catch (...) {
}
but you can be more specific
try {
auto result = calculate();
} catch (nosuccess) {
}
This could be a clean way, inspired by all other answers in this post:
template <typename T>
inline std::pair<bool, T> _unwrap(const std::optional<T> &val) {
return { val.has_value(), *val };
}
#define unwrap(x, val) const auto &[_##x, x] = _unwrap(val); (_##x)
Usage:
if (unwrap(result, calculateOptional())) {
// result is now equivalent to *calculateOptional()
}
Pros:
You don't mess with the if statement
It maintains a method-like feel to it
You can still add more conditions to the right of the if statement
Cons:
Read-only but then again optionals already are
Happy to hear of any issues/fixes you guys might think there might be with this solution.
I want my functions to return either an indication of success or an object that describes the nature of the failure. I'd normally use exceptions for this but I've been told not to use them for common code paths and this set of functions can be expected to fail fairly often for various reasons.
My thought is to use C++17's std::optional as I don't have to return a full error object when it's not needed. So with optional, if the function doesn't succeed it returns the error object, otherwise the optional is empty. The issue with that is it reverses the expectation of a returned value (i.e. true usually indicates success not failure).
I could get people to use an is_success function, which would be used like this, assuming Error is my error class:
auto result = do_stuff();
if (!is_success(result)) {
Error err = *result;
// ...
}
Or would a result class be more robust?
class MaybeError {
std::optional<Error> _error;
public:
MaybeError(const Error& error) : _error(error) {}
constexpr MaybeError() : _error({}) {}
explicit operator bool const() {
return !(_error.operator bool());
}
constexpr bool has_error() const {
return !(_error.has_value());
}
constexpr Error& error() & { return _error.value(); }
constexpr const Error & error() const & { return _error.value(); }
constexpr Error&& error() && { return std::move(_error.value()); }
constexpr const Error&& error() const && { return std::move(_error.value()); }
constexpr const Error* operator->() const { return _error.operator->(); }
constexpr Error* operator->() { return _error.operator->(); }
constexpr const Error& operator*() const& { return _error.operator*(); }
constexpr Error& operator*() & { return _error.operator*(); }
constexpr const Error&& operator*() const&& { return std::move(_error.operator*()); }
constexpr Error&& operator*() && { return std::move(_error.operator*()); }
};
Which can be used similarly to the first example:
auto result = do_stuff();
if (!result) {
Error err = *result;
// ...
}
What is the best option? Am I going about this the right way?
Edit To be clear, the do_stuff function that's being called doesn't return an object if it succeeds. If it always succeeded without error it'd just be void do_stuff().
Edit 2 In the comments Christian Hackl suggests a less over-engineered solution using a simple struct.
struct MaybeError {
std::optional<Error> error;
};
This would be both simpler and address my concern that people would expect functions to return true if successful by making it explicit that it is the error condition that is being tested for. E.g.:
auto result = do_stuff();
if (result.error) {
Error e = *t.error;
// ...
}
I played around a bit with boost::expected that was suggested by Nicol Bolas. It seems to be really nice for this use case:
#include <iostream>
#include <system_error>
#include <boost/expected/expected.hpp>
using ExpectedVoid = boost::expected< void, std::error_code >;
using ExpectedInt = boost::expected< int, std::error_code >;
ExpectedVoid do_stuff( bool wantSuccess ) {
if( wantSuccess )
return {};
return boost::make_unexpected( std::make_error_code( std::errc::operation_canceled ) );
}
ExpectedInt do_more_stuff( bool wantSuccess ) {
if( wantSuccess )
return 42;
return boost::make_unexpected( std::make_error_code( std::errc::operation_canceled ) );
}
int main()
{
for( bool wantSuccess : { false, true } )
{
if( auto res = do_stuff( wantSuccess ) )
std::cout << "do_stuff successful!\n";
else
std::cout << "do_stuff error: " << res.error() << "\n";
}
std::cout << "\n";
for( bool wantSuccess : { false, true } )
{
if( auto res = do_more_stuff( wantSuccess ) )
std::cout << "do_more_stuff successful! Result: " << *res << "\n";
else
std::cout << "do_more_stuff error: " << res.error() << "\n";
}
return 0;
}
Output:
do_stuff error: generic:105
do_stuff successful!
do_more_stuff error: generic:105
do_more_stuff successful! Result: 42
You can download the source from the link at the beginning and just throw the files from the "include" directory of the source into your boost include directory ("boost" sub folder).
There are types designed for this. One proposed for standardization (PDF) is expected<T, E>. It's basically like a variant which can either have the desired value or an "error code" (T can be void if you just want to check to see if a process succeeded).
Of course, you could use an actual variant if you have access to such an implementation. But expected has a nicer interface that's designed for this scenario. And unlike std::variant from C++17, the proposed expected cannot be valueless_by_exception, since E is required to be a nothrow-moveable type (not exactly a high bar for most error codes).
I am wanting to make a class which allows me to lock an object from being modified. It would essentially be a template with a boolean specifying the lock state. Since it is a template, I won't know all the methods that can be called on the internal object, so I need a method to pass calls through...
template<class T>
class const_lock
{
public:
const_lock() : my_lock(false) {}
void set_const_lock(bool state) {my_lock = state;}
// HOW TO IMPLEMENT SOMETHING LIKE THESE????
//
template<typename...Args >
auto operatorANY_OPERATOR (Args...args)
{
if(my_lock != false)
throw std::exception("Objected locked to modification");
return my_value.ANY_OPERATOR(args);
}
template<typename...Args >
auto operatorANY_CONST_OPERATOR (Args...args) const
{
return my_value.ANY_CONST_OPERATOR(args);
}
template<typename...Args >
auto ANY_METHOD(Args...args)
{
if(my_lock != false)
throw std::exception("Objected locked to modification");
return my_value.ANY_METHOD(args);
}
template<typename...Args >
auto ANY_CONST_METHOD(Args...args) const
{
return my_value.ANY_CONST_METHOD(args);
}
private:
bool my_lock;
T my_value;
}
int main()
{
const_lock<std::vector<int>> v;
v.push_back(5);
v.push_back(7);
v.set_const_lock(true);
v.push_back(9); // fails compilation
std::cout << v.at(1) << std::endl; // ok
}
Any help would be appreciated. Thanks!
Edit: changed static assert to throw and exception
What you're trying to do looks rather difficult, but more importantly is over-complicated and unnecessary for what you're trying to do.
Essentially what you're trying to do (correct me if I'm wrong) is create a compile time check of whether you are supposed to able to modify an object at a given time. However, c++ already has a built in way of doing this. Simply declare or pass your object as const or const&, and the compiler will not allow you to modify non-mutable parts of the object. When you want to be able to modify it pass it without const. You can even cast it from const& to regular & when you want to go from code where you can't modify it directly to code where you can, though I don't recommend it.
edit: just saw a comment on the question about no reference arrays. Don't worry about that! The standard library has support for reference wrappers which allow you to essentially store references in arrays or anywhere else.
You can make a generic wrapper class that you can forward the function to using a lambda that captures a reference to the internal member. In this example I am just using an if statement to check if it is "locked" and if it is then we just modify a copy.
template<class T>
class const_lock
{
private:
bool my_lock;
mutable T my_value;
public:
const_lock() : my_lock(false) {}
void set_const_lock() { my_lock = true; }
template<typename F>
auto operator()(F f) const -> decltype(f(my_value))
{
if (my_lock)
{
T temp{my_value}; // make a copy
return f(temp);
}
else
return f(my_value); // modify wrraped value
}
};
int main()
{
const_lock<std::string> cl;
cl([](std::string& s) {
s = "foobar";
});
cl([](std::string& s) {
std::cout << s << std::endl;
});
cl.set_const_lock();
cl([](std::string& s) {
s = "we should still be foobar";
});
cl([](std::string& s) {
std::cout << s;
});
}
This is completely unimplementable. A trivial modification of your source code shows why this won't work.
int main()
{
const_lock<std::vector<int>> v;
v.push_back(5);
v.push_back(7);
if (rand() % 2)
v.set_const_lock(true);
v.push_back(9); // fails compilation
std::cout << v.at(1) << std::endl; // ok
}
You need to completely rethink your approach.
Below is an example illustrating what I would be trying to protect against
class Node
{
public:
Node(int id) : my_id(id) {}
// . . .
int id() {return my_id;}
private:
int my_id;
// . . .
};
class Grid
{
public:
Grid() {}
// . . .
void associate(Node* n) { my_nodes.push_back(n); }
private:
// . . .
std::vector<Node*> my_nodes;
};
Node* find(std::vector<Node>& Nodes, int ID)
{
for(auto i=Nodes.begin(); i!=Nodes.end(); ++i)
{
if (i->id() == ID)
{
return &*i;
}
}
}
main()
{
std::vector<Node> Nodes;
// fill Nodes with data
Grid Array;
Array.associate( find(Nodes,14325) );
Array.associate( find(Nodes,51384) );
Array.associate( find(Nodes,321684) );
// . . .
Nodes.push_back(Node(21616)); // this can invalidate my pointers in Array
}
If I was able to make my Nodes vairable be
const_lock<std::vector<Node>> Nodes;
then call
Nodes.set_const_lock(true);
after populating the data, I wouldn't need to worry about my pointers in Array getting messed up.
I'm doing this:
template<typename T> class var_accessor {
public:
std::set<std::shared_ptr<T>> varset;
std::map<std::string,std::shared_ptr<T>> vars_by_name;
std::map<uint32,std::shared_ptr<T>> vars_by_id;
std::shared_ptr<T> operator[](const uint32& index) { return vars_by_id[index]; }
std::shared_ptr<T> operator[](const std::string& index) { return vars_by_name[index]; }
bool is_in_set(std::shared_ptr<T> what) { auto it = varset.find(what); if (it == varset.end()) return false; return true; }
bool is_in_set(uint32 what) { auto it = vars_by_id.find(what); if (it == vars_by_id.end()) return false; return true; }
bool is_in_set(std::string& what) { auto it = vars_by_name.find(what); if (it == vars_by_name.end()) return false; return true; }
bool place(std::shared_ptr<T> what, const uint32 whatid, const std::string& whatstring) {
if (is_in_set(what)) return false;
varset.emplace(what);
vars_by_name.emplace(whatstring,what);
vars_by_id.emplace(whatid,what);
return true;
}
};
Then...
class whatever {
std::string name;
std::function<int32()> exec;
};
And:
class foo {
public:
var_accessor<whatever> stuff;
};
This works:
std::shared_ptr<whatever> thing(new whatever);
thing->name = "Anne";
thing->exec = []() { return 1; }
foo person;
person.stuff.emplace(thing, 1, thing->name);
Getting the name crashes it:
std::cout << person.stuff[1]->name;
But if I change the operator[]'s to return references, it works fine.
I don't want to be able to accidentally add new elements without adding to all 3 structures, so that's why I made
std::shared_ptr<T> operator[]
instead of
std::shared_ptr<T>& operator[]
Is there any way to prevent assignment by subscript but keep the subscript operator working?
To be clear I want to be able to keep doing
std::cout << person.stuff[4];
But NOT be able to do
std::shared_ptr<whatever> bob(new whatever);
bob->name = "bob";
person.stuff[2] = bob;
The error is a EXC_BAD_ACCESS inside the std::string class madness
Everything I read says simply "don't return references if you want to prevent assignment" but it also prevents using it for me.
Yes I know some things should be made private but I just want to get it working first.
Using Clang/LLVM in XCode 5.1
Thanks!
You should return a const reference. See this question
A const reference means the caller is not allowed to change the value, only look at it. So assignment will be a compile-time error. But using it will work (and be efficient).