Alternative to operator()() overloading? || Direct member access - c++

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

Related

How best to test and unwrap std::optional in an if statement

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.

static_cast with unrelated classes

I have following class structure:
Now I have a Device pointer, where I know that it is of type WiredHeadphone or RadioHeadphone. I need to cast this pointer to HeadphoneInterface.
In a perfect world I would just use a dynamic_cast. Unfortunately I am on an embedded platform which does not support dynamic_cast at all. Currently I do this:
HeadphoneInterface *GetDeviceAsHeadphone(Device* dev) {
// use my own type system to identify the actual type and cast accordingly:
if(dev->GetType() == Type_WiredHeadphone) {
return static_cast<HeadphoneInterface*>((WiredHeadphone *)dev);
} else if(dev->GetType() == Type_RadioHeadphone) {
return static_cast<HeadphoneInterface*>((RadioHeadphone *)dev);
} else {
return NULL;
}
}
This is ugly as hell and not maintainable. There will be more Headphone devices in the future, and I don't want to update this function every time.
Is there a better way to solve this?
You can add a virtual function to Device interface that does the (cross) cast to HeadphoneInterface for you:
struct HeadphoneInterface;
struct Device {
// ...
virtual HeadphoneInterface* getHeadphoneInterface() noexcept { return 0; }
// ...
};
And override the function in WiredHeadphone and RadioHeadphone to return a non-null pointer to HeadphoneInterface:
struct WiredHeadphone : WiredDevice, HeadphoneInterface {
HeadphoneInterface* getHeadphoneInterface() noexcept override { return this; }
};
Then GetDeviceAsHeadphone becomes:
inline HeadphoneInterface* GetDeviceAsHeadphone(Device* dev) noexcept {
return dev->getHeadphoneInterface();
}
Notice that no explicit cast is required here.

std::vector of std::functions find

I have a vector populated with callback functions and I would like to check whether callback to the function already exists prior to adding it. I don't know whether it will even work bu so far it doesn't even compile.
vector<std::function<void(void*)>> _callbacks;
void Event::RegisterCallback(std::function<void(void*)> callback)
{
if (callback == NULL)
return;
vector<std::function<void(void*)>>::iterator it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end())
{
_callbacks.push_back(callback);
}
else
{
//print error
throw;
}
}
This gives a compile error:
"Overload resolution selected deleted operator '=='" in alorithm(805). This is related to the find function call.
How do I get this to work and is it even going to compare function calls to the same method properly?
Thanks
As noted in the comments the simplest solution is to use default C-style function pointers as they support == operator in opposite to C++11 function which does not.
using func_type = void(*)();
vector<func_type> _callbacks;
void Event::RegisterCallback(func_type callback)
{
if (callback == nullptr)
return;
auto it = std::find(_callbacks.begin(), _callbacks.end(), callback);
if (it == _callbacks.end()) {
_callbacks.push_back(callback);
}
else {
throw;
}
}
void f() {};
void g() {};
/*
evt.RegisterCallback(f); // works fine
evt.RegisterCallback(g); // works fine
evt.RegisterCallback(f); // throws exception
*/
If you don't like this approach you can write your own function-pointer class with support of equality operator.
Another solution is to have a class with a std::function member and another comperable member, and then overloading the () to get the std::function parameter and call it with the parameter, and the == operator to compeare the class using the comperable member.
CompareableFunction.h:
class CompareableFunction
{
public:
CompareableFunction(int nId, std::function<void(parameter)> handler);
~CompareableFunction();
void operator()(parameter param);
bool operator== (CompareableFunction compareableFunc);
private:
std::function<void(parameter)> m_handler;
int m_nId;
};
CompareableFunction.cpp:
CompareableFunction::CompareableFunction(int nId, std::function<void(parameter)> handler)
{
m_nId = nId;
m_handler = handler;
}
CompareableFunction::~CompareableFunction()
{
}
void CompareableFunction::operator()(parameter param)
{
return m_handler(param);
}
bool CompareableFunction::operator==(CompareableFunction compareableFunc)
{
return (m_nId == compareableFunc.m_nId);
}
EDIT: you can convert the std::function to a C-style function pointer and use it to compare. example to a conversion is here: http://www.cplusplus.com/forum/general/63552/

Can I avoid all this multiples try/catch

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.

Get list of functions in a namespace at runtime?

Is it possible to get a list of functions in a certain namespace or all functions in a program at runtime?
I have a function pointer map and I need to add commands on my own to it, but I thought: why not create a namespace and let the program do the work at runtime?
something like(pseudocode):
typedef bool (*command)(void);
namespace Commands
{
bool Start(void)
{
return true;
}
bool End(void)
{
return true;
}
};
std::map<std::string,command> CommandMap;
main()
{
for(each function in namespace Commands)
{
CommandMap[std::string(function_name)] = function;
}
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
instead of
std::map<std::string,command> CommandMap;
main()
{
CommandMap["Start"] = Commands::Start;
CommandMap["End"] = Commands::End;
//list of thousands of other commands......
CommandMap["Start"]();
CommandMap["End"]();
return 0;
}
Is this possible to achieve in C++ or C++11? Or any alternatives to my goal?
No (it has to be 30 characters).
EDIT: This goes along with my comment about how much control you have. You could redefine all of your functions as functors, and have the constructor register itself with some array. Your base class would look like this:
EDIT2: read the comment about all functions having same arguments and return types, makes it a little cleaner.
class myFunctorBaseClass
{
public:
myFunctorClass () : {//register myself, no duplicates}
virtual int operator () (int);//Whatever types you want
};
class myFunctor: public myFunctorBaseClass //Define as many of these as you need
{
public:
int operator() (int y) { return y; } // Define this as whatever you want
}
This obviously would depend on the objects being constucted, but assuming they all were as an initialization step, this would get you what you want.
NOTE: This may be incomplete/not compile. I just kinda wrote this off the top of my head, but it should be close. The reference you want is "functors" if you have questions about how this works.
Consider something like:
class CommandCollection
{
...
void register_command(Command*, string);
map<string, Command*> m_command_map;
}
class Command
{
...
virtual do_command(...) = 0;
}
class EachCommand : public Command
{
EachCommand() { CommandCollection::instance().register_command(this, my_name); }
...
virtual do_command(...);
}
EachCommand each_command_inst;
The Command base class has a virtual to do a command. Each derived type implements the command (you could try overloading the () operator to make them look more like functions).
Each derived Command registers itself with the CommandCollection, so it can be known in a central location. If you want to associate the commands by string (seems good if a user is typing them in), then that would be the key in the map.
As mentioned elsewhere, names (in C and C++, other languages may/do differ on this point) only really exist as part of the source-code. Once compiled, the names cease to have any meaning in C and C++.
One could, however, consider some sort of structure like this:
class CommandBase
{
virtual bool doCommand() = 0;
virtual std::string name() = 0;
virtual ~CommandBase() {}
};
class StartCommand : public CommandBase
{
bool doCommand() { ...; return true }
std::string name() { return "Start"; }
};
void RegisterCommand(CommandBase *cmd)
{
CommandMap[cmd->name] = cmd;
}
...
StartCommand start;
...
void someFunction()
{
RegisterCommand(&start);
}
I'll probably get a downvote for mentioning macros, because these are evil - don't use this if you are a purist that don't like macros.
#define CMD(x) CommandMap[#x] = Command::x
CMD(start);
CMD(end);
There are certainly other variants, and someone who knows templates may well come up with something that does this using templates.