Okay, this is just a minor caveat. I am currently working with the lovely ArcSDK from ESRI. Now to get a value from any of their functions, you basically have to pass the variable, you want to assign the value to.
E.g.:
long output_width;
IRasterProps->get_Width(&output_width);
Its such a minor thing, but when you have to pick out around 30 different pieces of data from their miscellaneous functions, it really starts to get annoying.
So what i was wondering is it possible to somehow by the magic of STL or C++ change this into:
long output_width = IRasterProps->get_Width(<something magical>);
All of the functions return void, otherwise the off chance some of them might return a HRESULT, which i can safely ignore. Any ideas?
***EDIT****
Heres the final result i got which works :)!!!!!
A magic(P p, R (__stdcall T::*f)(A *)) {
A a;
((*p).*f)(&a);
return a;
}
I know I've already answered, but here's another way. It's better in that it's faster (no boost::function overhead) and avoids the binders (since people seem to have an aversion to them), but is worse in that it's much less general (since it only works for one-argument member functions).
template <typename P, typename T, typename A>
A magic(P p, void (T::*f)(A &)) {
A a;
((*p).*f)(a);
return a;
}
Which you'd call like this:
long output_width = magic(raster_props_object, &IRasterProps::get_Width);
Or, if you happen to be using GCC, we can use some more tricks:
#define MORE_MAGIC(p,f) ({ \
typedef __typeof(*(p)) big_ugly_identifier; \
magic((p),(&big_ugly_identifier::f)); \
})
Which will let us do this:
long output_width = MORE_MAGIC(raster_props_object, get_Width);
(Bonus points if the naming conventions made you think of a PDP-10.)
EDIT: Updated to take any pointer-like type, so it will now work with shared_ptr, iterators, and hopefully _com_ptr.
EDIT: Oops, they're pointers, not references. Here's a version (or overload) that deals with that, and allows -- by ignoring -- arbitrarily-typed return values.
template <typename P, typename T, typename A, typename R>
A magic(P p, R (T::*f)(A *)) {
A a;
((*p).*f)(&a);
return a;
}
This is not quite what you specified because you need to wrap get() around the method, but it works:
template<class T, class S>
T get(S fun(T&)) {
T result;
fun(result);
return result;
}
void foo(int& x) {
x = 5;
}
bool bar(char& x) {
x = 'c';
return false;
}
int main() {
int x = get(foo);
char y = get(bar);
return 0;
}
Can you derive from IRasterProps? Being that the case you can construct your own interface to it.
EDIT: Following on the concept you can probably also apply the Adapter design pattern (or even a Facade if you wish to apply a common interface to several like-minded classes of the SDK).
Looks like a COM object to me.
Visual C++ supports an #import directive to import the type library, and create high-legel wrappers. So you either end up with
width = ptr->GetWidth();
or - even better -
width = ptr->Width;
If a function fails, the HRESULT returned will be transformed into an _com_error exception.
I've used that successfully on many OS and 3rd party COM objects, makes them much easier to use.
Note that you control the wrapper generation through options, the first thing I do is usually adding a rename_namespace or no_namespace, because otherwise the symbold end up in a namespace depending on the typelib name, which is usually ugly.
also, unless you use named_guids option, you might needto change CLSID_xxx and IID_xxx constants to __uuidof(xxx).
EDIT: In retrospect, I'm not sure this one will actually work, since I don't think the template arguments will deduce. Buyer Beware.
Sure! What you need is something to which you can pass a function that will call it and return you the outputted value.
Here's the easy, if less efficient way:
template <typename T>
T magic(boost::function<void(T&)> f) {
T x;
f(x);
return x;
}
Which you'd then call like this using boost::lambda:
long output_width = magic(raster_props_object->*&IRasterProps::get_Width);
Or like this, using boost::bind:
long output_width = magic(bind(&IRasterProps::get_Width, raster_props_object, _1));
You can get rid of boost::function, but that's uglier. Probably worth it, though.
Don't think this is possible. Assigning void to a long should be an error in any case.
Remember, it's probably more performant to pass-by-reference than to return a large object. (won't really make a difference with long's though)
Compiling this:
void foo(long &a) {
}
int main(void) {
long a=0;
a = foo(a);
return 0;
}
gives this error:
g++ x.cc
x.cc: In function ‘int main()’:
x.cc:9: error: void value not ignored as it ought to be
I'm not aware of something insane you could do, precisely like you're asking, and if there was some insane hackery that did work on some peculiar platform I'm pretty sure in a code-review I'd hate it.
It may may more sense to either...
define some trivial inline function wrappers around the APIs you care about
make a specialized class descend from IRasterProps (or whatever) that provides the appropriate accessor methods.
Either of those will impact maintenance time of the code but would safely and cleanly give you the call syntax you are looking for.
Related
The Goal:
decide during runtime which templated function to use and then use it later without needing the type information.
A Partial Solution:
for functions where the parameter itself is not templated we can do:
int (*func_ptr)(void*) = &my_templated_func<type_a,type_b>;
this line of code can be modified for use in an if statement with different types for type_a and type_b thus giving us a templated function whose types are determined during runtime:
int (*func_ptr)(void*) = NULL;
if (/* case 1*/)
func_ptr = &my_templated_func<int, float>;
else
func_ptr = &my_templated_func<float, float>;
The Remaining Problem:
How do I do this when the parameter is a templated pointer?
for example, this is something along the lines of what I would like to do:
int (*func_ptr)(templated_struct<type_a,type_b>*); // This won't work cause I don't know type_a or type_b yet
if (/* case 1 */) {
func_ptr = &my_templated_func<int,float>;
arg = calloc(sizeof(templated_struct<int,float>, 1);
}
else {
func_ptr = &my_templated_func<float,float>;
arg = calloc(sizeof(templated_struct<float,float>, 1);
}
func_ptr(arg);
except I would like type_a, and type_b to be determined during runtime. I see to parts to the problem.
What is the function pointers type?
How do I call this function?
I think I have the answer for (2): simply cast the parameter to void* and the template function should do an implicit cast using the function definition (lease correct me if this won't work as I think it will).
(1) is where I am getting stuck since the function pointer must include the parameter types. This is different from the partial solution because for the function pointer definition we were able to "ignore" the template aspect of the function since all we really need is the address of the function.
Alternatively there might be a much better way to accomplish my goal and if so I am all ears.
Thanks to the answer by #Jeffrey I was able to come up with this short example of what I am trying to accomplish:
template <typename A, typename B>
struct args_st {
A argA;
B argB;
}
template<typename A, typename B>
void f(struct args_st<A,B> *args) {}
template<typename A, typename B>
void g(struct args_st<A,B> *args) {}
int someFunction() {
void *args;
// someType needs to know that an args_st struct is going to be passed
// in but doesn't need to know the type of A or B those are compiled
// into the function and with this code, A and B are guaranteed to match
// between the function and argument.
someType func_ptr;
if (/* some runtime condition */) {
args = calloc(sizeof(struct args_st<int,float>), 1);
f((struct args_st<int,float> *) args); // this works
func_ptr = &g<int,float>; // func_ptr should know that it takes an argument of struct args_st<int,float>
}
else {
args = calloc(sizeof(struct args_st<float,float>), 1);
f((struct args_st<float,float> *) args); // this also works
func_ptr = &g<float,float>; // func_ptr should know that it takes an argument of struct args_st<float,float>
}
/* other code that does stuff with args */
// note that I could do another if statement here to decide which
// version of g to use (like I did for f) I am just trying to figure out
// a way to avoid that because the if statement could have a lot of
// different cases similarly I would like to be able to just write one
// line of code that calls f because that could eliminate many lines of
// (sort of) duplicate code
func_ptr(args);
return 0; // Arbitrary value
}
Can't you use a std::function, and use lambdas to capture everything you need? It doesn't appear that your functions take parameters, so this would work.
ie
std::function<void()> callIt;
if(/*case 1*/)
{
callIt = [](){ myTemplatedFunction<int, int>(); }
}
else
{
callIt = []() {myTemplatedFunction<float, float>(); }
}
callIt();
If I understand correctly, What you want to do boils down to:
template<typename T>
void f(T)
{
}
int somewhere()
{
someType func_ptr;
int arg = 0;
if (/* something known at runtime */)
{
func_ptr = &f<float>;
}
else
{
func_ptr = &f<int>;
}
func_ptr(arg);
}
You cannot do that in C++. C++ is statically typed, the template types are all resolved at compile time. If a construct allowed you to do this, the compiler could not know which templates must be instanciated with which types.
The alternatives are:
inheritance for runtime polymorphism
C-style void* everywhere if you want to deal yourself with the underlying types
Edit:
Reading the edited question:
func_ptr should know that it takes an argument of struct args_st<float,float>
func_ptr should know that it takes an argument of struct args_st<int,float>
Those are incompatible. The way this is done in C++ is by typing func_ptr accordingly to the types it takes. It cannot be both/all/any.
If there existed a type for func_ptr so that it could take arguments of arbitrary types, then you could pass it around between functions and compilation units and your language would suddenly not be statically typed. You'd end up with Python ;-p
Maybe you want something like this:
#include <iostream>
template <typename T>
void foo(const T& t) {
std::cout << "foo";
}
template <typename T>
void bar(const T& t) {
std::cout << "bar";
}
template <typename T>
using f_ptr = void (*)(const T&);
int main() {
f_ptr<int> a = &bar<int>;
f_ptr<double> b = &foo<double>;
a(1);
b(4.2);
}
Functions taking different parameters are of different type, hence you cannot have a f_ptr<int> point to bar<double>. Otherwise, functions you get from instantiating a function template can be stored in function pointers just like other functions, eg you can have a f_ptr<int> holding either &foo<int> or &bar<int>.
Disclaimer: I have already provided an answer that directly addresses the question. In this answer, I would like to side-step the question and render it moot.
As a rule of thumb, the following code structure is an inferior design in most procedural languages (not just C++).
if ( conditionA ) {
// Do task 1A
}
else {
// Do task 1B
}
// Do common tasks
if ( conditionA ) {
// Do task 2A
}
else {
// Do task 2B
}
You seem to have recognized the drawbacks in this design, as you are trying to eliminate the need for a second if-else in someFunction(). However, your solution is not as clean as it could be.
It is usually better (for code readability and maintainability) to move the common tasks to a separate function, rather than trying to do everything in one function. This gives a code structure more like the following, where the common tasks have been moved to the function foo().
if ( conditionA ) {
// Do task 1A
foo( /* arguments might be needed */ );
// Do task 2A
}
else {
// Do task 1B
foo( /* arguments might be needed */ );
// Do task 2B
}
As a demonstration of the utility of this rule of thumb, let's apply it to someFunction(). ... and eliminate the need for dynamic memory allocation ... and a bit of cleanup ... unfortunately, addressing that nasty void* is out-of-scope ... I'll leave it up to the reader to evaluate the end result. The one feature I will point out is that there is no longer a reason to consider storing a "generic templated function pointer", rendering the asked question moot.
// Ideally, the parameter's type would not be `void*`.
// I leave that for a future refinement.
void foo(void * args) {
/* other code that does stuff with args */
}
int someFunction(bool condition) {
if (/* some runtime condition */) {
args_st<int,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
else {
args_st<float,float> args;
foo(&args);
f(&args); // Next step: pass by reference instead of passing a pointer
}
return 0;
}
Your choice of manual memory management and over-use of the keyword struct suggests you come from a C background and have not yet really converted to C++ programming. As a result, there are many areas for improvement, and you might find that your current approach should be tossed. However, that is a future step. There is a learning process involved, and incremental improvements to your current code is one way to get there.
First, I'd like to get rid of the C-style memory management. Most of the time, using calloc in C++ code is wrong. Let's replace the raw pointer with a smart pointer. A shared_ptr looks like it will help the process along.
// Instead of a raw pointer to void, use a smart pointer to void.
std::shared_ptr<void> args;
// Use C++ memory management, not calloc.
args = std::make_shared<args_st<int,float>>();
// or
args = std::make_shared<args_st<float,float>>();
This is still not great, as it still uses a pointer to void, which is rarely needed in C++ code unless interfacing with a library written in C. It is, though, an improvement. One side effect of using a pointer to void is the need for casts to get back to the original type. This should be avoided. I can address this in your code by defining correctly-typed variables inside the if statement. The args variable will still be used to hold your pointer once the correctly-typed variables go out of scope.
More improvements along this vein can come later.
The key improvement I would make is to use the functional std::function instead of a function pointer. A std::function is a generalization of a function pointer, able to do more albeit with more overhead. The overhead is warranted here in the interest of robust code.
An advantage of std::function is that the parameter to g() does not need to be known by the code that invokes the std::function. The old style of doing this was std::bind, but lambdas provide a more readable approach. Not only do you not have to worry about the type of args when it comes time to call your function, you don't even need to worry about args.
int someFunction() {
// Use a smart pointer so you do not have to worry about releasing the memory.
std::shared_ptr<void> args;
// Use a functional as a more convenient alternative to a function pointer.
// Note the lack of parameters (nothing inside the parentheses).
std::function<void()> func;
if ( /* some runtime condition */ ) {
// Start with a pointer to something other than void.
auto real_args = std::make_shared<args_st<int,float>>();
// An immediate function call:
f(real_args.get());
// Choosing a function to be called later:
// Note that this captures a pointer to the data, not a copy of the data.
// Hence changes to the data will be reflected when this is invoked.
func = [real_args]() { g(real_args.get()); };
// It's only here, as real_args is about to go out of scope, where
// we lose the type information.
args = real_args;
}
else {
// Similar to the above, so I'll reduce the commentary.
auto real_args = std::make_shared<args_st<float,float>>();
func = [real_args]() { g(real_args.get()); };
args = real_args;
}
/* other code that does stuff with args */
/* This code is probably poor C++ style, but that can be addressed later. */
// Invoke the function.
func();
return 0;
}
Your next step probably should be to do some reading on these features so you understand what this code does. Then you should be in a better position to leverage the power of C++.
Possible duplicates I'll explain at the bottom.
I was wondering if it is possible to do a compile time check to see if a function is called before another function.
My use case looks something like this:
auto f = foo();
if(!f.isOk())
return f.getError();
auto v = f.value();
So in this case I would want to get a compile time error if the user did not call isOk before calling value.
As far as I know and searched it does not seem possible but I wanted to ask here just to be sure I didn't miss any c++ magic.
FauxDupes:
How to check at compile time that a function may be called at compile time?
This is about knowing wether your function is a constexpr function. I want to know if one function has been called before the other has been called.
What you want is not possible directly without changing your design substantially.
What you can do is enforce calling always both by wrapping them in a single call:
??? foo(const F& f) {
return f.isOk() ? f.value() : f.getError();
}
However, this just shifts the problem to choosing the return type. You could return a std::variant or with some changes on the design a std::optional, but whatever you do it will be left to the caller to check what actually has been returned.
Don't assume the most stupid user and don't try to protect them from any possible mistake. Instead assume that they do read documentation.
Having to check whether a returned value is valid is a quite common pattern: functions that return a pointer can return a null-pointer, functions returning an iterator can return the end iterator. Such cases are well documented and a responsible caller will check if the returned value is valid.
To get further inspiration I refer you to std::optional, a quite modern addition to C++, which also heavily relies on the user to know what they are dealing with.
PS: Just as one counter-example, a user might write code like this, which makes it impossible to make the desired check at compile time with your current design:
int n;
std::cin >> n;
auto f = foo();
if(n > 10 && !f.isOk())
return f.getError();
auto v = f.value();
One strategy for this kind of thing is to leverage __attribute__((warn_unused_result)) (for GCC) or _Check_return_ (msvc).
Then, change foo() to return the error condition:
SomeObj obj;
auto result = foo(obj);
This will nudge the caller into handling the error. Of course there are obvious limitations: foo() cannot be a constructor, for example, and the caller cannot use auto for the typename.
One way to ensure order is to transform the temporary dependency into physical dependency:
Move method F::getError() and F::value() into their own structure wrapper (Error, Value).
Change bool F::isOk() to something like:
std::variant<Error, Value> F::isOk()
Then, you cannot use Error::getError or Value::value() before calling isOk, as expected:
auto f = foo();
auto isOk = f.isOk();
if (auto* e = std::get_if<Error>(&isOk)) // Or std::visit
return e->getError();
auto& value = std::get<Value>(&isOk);
auto v = value.value();
C++17 has a new attribute, [[nodiscard]].
Suppose, that I have a Result struct, which has this attribute:
struct [[nodiscard]] Result {
};
Now, if I call a function which returns Result, I got a warning if I don't check the returned Result:
Result someFunction();
int main() {
someFunction(); // warning here, as I don't check someFunction's return value
}
This program generates:
warning: ignoring return value of function declared with 'nodiscard'
attribute [-Wunused-result]
So far, so good. Now suppose, that I have a special function, for which I still want to return Result, but I don't want this warning generated, if the check is omitted:
Result someNonCriticalFunction();
int main() {
someNonCriticalFunction(); // I don't want to generate a warning here
}
It is because, someNonCriticalFunction() does something non-critical (for example, something like printf - I bet that no-one checks printf's return value all the time); most cases, I don't care if it fails. But I still want it to return Result, as in some rare cases, I do need its Result.
Is it possible to do this somehow?
Possible solutions which I don't like:
I would not like calling it as (void)someNonCriticalFunction(), because this function is called a lot of times, it is awkward
creating a wrapper around someNonCriticalFunction(), which calls (void)someNonCriticalFunction(): I don't want to have a differently named function just because of this
removing [[nodiscard]] from Result, and add it to every function which returns Result
Why not make use of std::ignore from the <tuple> header—that would make the discard explicit:
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
std::ignore = MyFunction();
return 0;
}
Compiler explorer of this code snippet: https://godbolt.org/z/eGPsjajz8
CPP Reference for std::ignore: https://en.cppreference.com/w/cpp/utility/tuple/ignore
I recommend the option you ruled out:
"removing [[nodiscard]] from Result, and add it to every function which returns Result."
But since you don't seem happy with it, here's another solution, using bog-standard inheritance:
struct [[nodiscard]] Result {
};
struct DiscardableResult: public Result {
};
For the functions where you can discard the result, use DiscardableResult as return type:
Result func1();
DiscardableResult func2();
func1(); // will warn
func2(); // will not warn
They say that every problem in computer science can be solved by adding another layer of indirection:
template <bool nodiscard=true>
struct Result;
template <>
struct Result<false> {
// the actual implementation
};
template <>
struct [[nodiscard]] Result<true>
: Result<false>
{
using Result<false>::Result;
};
This is effectively making Result conditionally [[nodiscard]], which allows:
Result<true> someFunction();
Result<false> someNonCriticalFunction();
int main() {
someFunction(); // warning here
someNonCriticalFunction(); // no warning here
}
Although really, this is identical to:
removing [[nodiscard]] from Result, and add it to every function which returns Result
which gets my vote to begin with.
You can suppress the warning with another C++17 attribute, namely [[maybe_unused]]
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
[[maybe_unused]] auto v = MyFunction();
return 0;
}
This way you also avoid the confusing dependency to std::tuple which comes with std::ignore, even CppCoreGuidelines is openly recommending to use std::ignore for ignoring [[nodiscard]] values:
Never cast to (void) to ignore a [[nodiscard]]return value. If you
deliberately want to discard such a result, first think hard about
whether that is really a good idea (there is usually a good reason the
author of the function or of the return type used [[nodiscard]] in the
first place). If you still think it's appropriate and your code
reviewer agrees, use std::ignore = to turn off the warning which is
simple, portable, and easy to grep.
Looking at C++ reference, officially std::ignore is only specified to be used in std::tie when unpacking tuples.
While the behavior of std::ignore outside of std::tie is not formally
specified, some code guides recommend using std::ignore to avoid
warnings from unused return values of [[nodiscard]] functions.
cast the result to a (void *).
int main()
{
(void *)someFunction(); //Warning will be gone.
}
This way you "used" your result as far as the compiler is concerned. Great for when you are using a library where nodiscard has been used and you really don't care to know the result.
So I ran across this (IMHO) very nice idea of using a composite structure of a return value and an exception - Expected<T>. It overcomes many shortcomings of the traditional methods of error handling (exceptions, error codes).
See the Andrei Alexandrescu's talk (Systematic Error Handling in C++) and its slides.
The exceptions and error codes have basically the same usage scenarios with functions that return something and the ones that don't. Expected<T>, on the other hand, seems to be targeted only at functions that return values.
So, my questions are:
Have any of you tried Expected<T> in practice?
How would you apply this idiom to functions returning nothing (that is, void functions)?
Update:
I guess I should clarify my question. The Expected<void> specialization makes sense, but I'm more interested in how it would be used - the consistent usage idiom. The implementation itself is secondary (and easy).
For example, Alexandrescu gives this example (a bit edited):
string s = readline();
auto x = parseInt(s).get(); // throw on error
auto y = parseInt(s); // won’t throw
if (!y.valid()) {
// ...
}
This code is "clean" in a way that it just flows naturally. We need the value - we get it. However, with expected<void> one would have to capture the returned variable and perform some operation on it (like .throwIfError() or something), which is not as elegant. And obviously, .get() doesn't make sense with void.
So, what would your code look like if you had another function, say toUpper(s), which modifies the string in-place and has no return value?
Have any of you tried Expected; in practice?
It's quite natural, I used it even before I saw this talk.
How would you apply this idiom to functions returning nothing (that is, void functions)?
The form presented in the slides has some subtle implications:
The exception is bound to the value.
It's ok to handle the exception as you wish.
If the value ignored for some reasons, the exception is suppressed.
This does not hold if you have expected<void>, because since nobody is interested in the void value the exception is always ignored. I would force this as I would force reading from expected<T> in Alexandrescus class, with assertions and an explicit suppress member function. Rethrowing the exception from the destructor is not allowed for good reasons, so it has to be done with assertions.
template <typename T> struct expected;
#ifdef NDEBUG // no asserts
template <> class expected<void> {
std::exception_ptr spam;
public:
template <typename E>
expected(E const& e) : spam(std::make_exception_ptr(e)) {}
expected(expected&& o) : spam(std::move(o.spam)) {}
expected() : spam() {}
bool valid() const { return !spam; }
void get() const { if (!valid()) std::rethrow_exception(spam); }
void suppress() {}
};
#else // with asserts, check if return value is checked
// if all assertions do succeed, the other code is also correct
// note: do NOT write "assert(expected.valid());"
template <> class expected<void> {
std::exception_ptr spam;
mutable std::atomic_bool read; // threadsafe
public:
template <typename E>
expected(E const& e) : spam(std::make_exception_ptr(e)), read(false) {}
expected(expected&& o) : spam(std::move(o.spam)), read(o.read.load()) {}
expected() : spam(), read(false) {}
bool valid() const { read=true; return !spam; }
void get() const { if (!valid()) std::rethrow_exception(spam); }
void suppress() { read=true; }
~expected() { assert(read); }
};
#endif
expected<void> calculate(int i)
{
if (!i) return std::invalid_argument("i must be non-null");
return {};
}
int main()
{
calculate(0).suppress(); // suppressing must be explicit
if (!calculate(1).valid())
return 1;
calculate(5); // assert fails
}
Even though it might appear new for someone focused solely on C-ish languages, to those of us who had a taste of languages supporting sum-types, it's not.
For example, in Haskell you have:
data Maybe a = Nothing | Just a
data Either a b = Left a | Right b
Where the | reads or and the first element (Nothing, Just, Left, Right) is just a "tag". Essentially sum-types are just discriminating unions.
Here, you would have Expected<T> be something like: Either T Exception with a specialization for Expected<void> which is akin to Maybe Exception.
Like Matthieu M. said, this is something relatively new to C++, but nothing new for many functional languages.
I would like to add my 2 cents here: part of the difficulties and differences are can be found, in my opinion, in the "procedural vs. functional" approach. And I would like to use Scala (because I am familiar both with Scala and C++, and I feel it has a facility (Option) which is closer to Expected<T>) to illustrate this distinction.
In Scala you have Option[T], which is either Some(t) or None.
In particular, it is also possible to have Option[Unit], which is morally equivalent to Expected<void>.
In Scala, the usage pattern is very similar and built around 2 functions: isDefined() and get(). But it also have a "map()" function.
I like to think of "map" as the functional equivalent of "isDefined + get":
if (opt.isDefined)
opt.get.doSomething
becomes
val res = opt.map(t => t.doSomething)
"propagating" the option to the result
I think that here, in this functional style of using and composing options, lies the answer to your question:
So, what would your code look like if you had another function, say toUpper(s), which modifies the string in-place and has no return value?
Personally, I would NOT modify the string in place, or at least I will not return nothing. I see Expected<T> as a "functional" concept, that need a functional pattern to work well: toUpper(s) would need to either return a new string, or return itself after modification:
auto s = toUpper(s);
s.get(); ...
or, with a Scala-like map
val finalS = toUpper(s).map(upperS => upperS.someOtherManipulation)
if you don't want to follow a functional route, you can just use isDefined/valid and write your code in a more procedural way:
auto s = toUpper(s);
if (s.valid())
....
If you follow this route (maybe because you need to), there is a "void vs. unit" point to make: historically, void was not considered a type, but "no type" (void foo() was considered alike a Pascal procedure). Unit (as used in functional languages) is more seen as a type meaning "a computation". So returning a Option[Unit] does make more sense, being see as "a computation that optionally did something". And in Expected<void>, void assumes a similar meaning: a computation that, when it does work as intended (where there are no exceptional cases), just ends (returning nothing). At least, IMO!
So, using Expected or Option[Unit] could be seen as computations that maybe produced a result, or maybe not. Chaining them will prove it difficult:
auto c1 = doSomething(s); //do something on s, either succeed or fail
if (c1.valid()) {
auto c2 = doSomethingElse(s); //do something on s, either succeed or fail
if (c2.valid()) {
...
Not very clean.
Map in Scala makes it a little bit cleaner
doSomething(s) //do something on s, either succeed or fail
.map(_ => doSomethingElse(s) //do something on s, either succeed or fail
.map(_ => ...)
Which is better, but still far from ideal. Here, the Maybe monad clearly wins... but that's another story..
I've been pondering the same question since I've watched this video. And so far I didn't find any convincing argument for having Expected, for me it looks ridiculous and against clarity&cleanness. I have come up with the following so far:
Expected is good since it has either value or exceptions, we not forced to use try{}catch() for every function which is throwable. So use it for every throwing function which has return value
Every function that doesn't throw should be marked with noexcept. Every.
Every function that returns nothing and not marked as noexcept should be wrapped by try{}catch{}
If those statements hold then we have self-documented easy to use interfaces with only one drawback: we don't know what exceptions could be thrown without peeking into implementation details.
Expected impose some overheads to the code since if you have some exception in the guts of your class implementation(e.g. deep inside private methods) then you should catch it in your interface method and return Expected. While I think it is quite tolerable for the methods which have a notion for returning something I believe it brings mess and clutter to the methods which by design have no return value. Besides for me it is quite unnatural to return thing from something that is not supposed to return anything.
It should be handled with compiler diagnostics. Many compilers already emit warning diagnostics based on expected usages of certain standard library constructs. They should issue a warning for ignoring an expected<void>.
Certain situations in my code, I end up invoking the function only if that function is defined, or else I should not. How can I achieve this?
like:
if (function 'sum' exists ) then invoke sum ()
Maybe the other way around to ask this question is how to determine if function is defined at runtime and if so, then invoke?
When you declare 'sum' you could declare it like:
#define SUM_EXISTS
int sum(std::vector<int>& addMeUp) {
...
}
Then when you come to use it you could go:
#ifdef SUM_EXISTS
int result = sum(x);
...
#endif
I'm guessing you're coming from a scripting language where things are all done at runtime. The main thing to remember with C++ is the two phases:
Compile time
Preprocessor runs
template code is turned into real source code
source code is turned in machine code
runtime
the machine code is run
So all the #define and things like that happen at compile time.
....
If you really wanted to do it all at runtime .. you might be interested in using some of the component architecture products out there.
Or maybe a plugin kind of architecture is what you're after.
Using GCC you can:
void func(int argc, char *argv[]) __attribute__((weak)); // weak declaration must always be present
// optional definition:
/*void func(int argc, char *argv[]) {
printf("FOUND THE FUNCTION\n");
for(int aa = 0; aa < argc; aa++){
printf("arg %d = %s \n", aa, argv[aa]);
}
}*/
int main(int argc, char *argv[]) {
if (func){
func(argc, argv);
} else {
printf("did not find the function\n");
}
}
If you uncomment func it will run it otherwise it will print "did not find the function\n".
While other replies are helpful advices (dlsym, function pointers, ...), you cannot compile C++ code referring to a function which does not exist. At minimum, the function has to be declared; if it is not, your code won't compile. If nothing (a compilation unit, some object file, some library) defines the function, the linker would complain (unless it is weak, see below).
But you should really explain why you are asking that. I can't guess, and there is some way to achieve your unstated goal.
Notice that dlsym often requires functions without name mangling, i.e. declared as extern "C".
If coding on Linux with GCC, you might also use the weak function attribute in declarations. The linker would then set undefined weak symbols to null.
addenda
If you are getting the function name from some input, you should be aware that only a subset of functions should be callable that way (if you call an arbitrary function without care, it will crash!) and you'll better explicitly construct that subset. You could then use a std::map, or dlsym (with each function in the subset declared extern "C"). Notice that dlopen with a NULL path gives a handle to the main program, which you should link with -rdynamic to have it work correctly.
You really want to call by their name only a suitably defined subset of functions. For instance, you probably don't want to call this way abort, exit, or fork.
NB. If you know dynamically the signature of the called function, you might want to use libffi to call it.
I suspect that the poster was actually looking for something more along the lines of SFINAE checking/dispatch. With C++ templates, can define to template functions, one which calls the desired function (if it exists) and one that does nothing (if the function does not exist). You can then make the first template depend on the desired function, such that the template is ill-formed when the function does not exist. This is valid because in C++ template substitution failure is not an error (SFINAE), so the compiler will just fall back to the second case (which for instance could do nothing).
See here for an excellent example: Is it possible to write a template to check for a function's existence?
use pointers to functions.
//initialize
typedef void (*PF)();
std::map<std::string, PF> defined_functions;
defined_functions["foo"]=&foo;
defined_functions["bar"]=&bar;
//if defined, invoke it
if(defined_functions.find("foo") != defined_functions.end())
{
defined_functions["foo"]();
}
If you know what library the function you'd like to call is in, then you can use dlsym() and dlerror() to find out whether or not it's there, and what the pointer to the function is.
Edit: I probably wouldn't actually use this approach - instead I would recommend Matiu's solution, as I think it's much better practice. However, dlsym() isn't very well known, so I thought I'd point it out.
You can use #pragma weak for the compilers that support it (see the weak symbol wikipedia entry).
This example and comment is from The Inside Story on Shared Libraries and Dynamic Loading:
#pragma weak debug
extern void debug(void);
void (*debugfunc)(void) = debug;
int main() {
printf(“Hello World\n”);
if (debugfunc) (*debugfunc)();
}
you can use the weak pragma to force the linker to ignore unresolved
symbols [..] the program compiles and links whether or not debug()
is actually defined in any object file. When the symbol remains
undefined, the linker usually replaces its value with 0. So, this
technique can be a useful way for a program to invoke optional code
that does not require recompiling the entire application.
So another way, if you're using c++11 would be to use functors:
You'll need to put this at the start of your file:
#include <functional>
The type of a functor is declared in this format:
std::function< return_type (param1_type, param2_type) >
You could add a variable that holds a functor for sum like this:
std::function<int(const std::vector<int>&)> sum;
To make things easy, let shorten the param type:
using Numbers = const std::vectorn<int>&;
Then you could fill in the functor var with any one of:
A lambda:
sum = [](Numbers x) { return std::accumulate(x.cbegin(), x.cend(), 0); } // std::accumulate comes from #include <numeric>
A function pointer:
int myFunc(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
sum = &myFunc;
Something that 'bind' has created:
struct Adder {
int startNumber = 6;
int doAdding(Numbers nums) {
int result = 0;
for (int i : nums)
result += i;
return result;
}
};
...
Adder myAdder{2}; // Make an adder that starts at two
sum = std::bind(&Adder::doAdding, myAdder);
Then finally to use it, it's a simple if statement:
if (sum)
return sum(x);
In summary, functors are the new pointer to a function, however they're more versatile. May actually be inlined if the compiler is sure enough, but generally are the same as a function pointer.
When combined with std::bind and lambda's they're quite superior to old style C function pointers.
But remember they work in c++11 and above environments. (Not in C or C++03).
In C++, a modified version of the trick for checking if a member exists should give you what you're looking for, at compile time instead of runtime:
#include <iostream>
#include <type_traits>
namespace
{
template <class T, template <class...> class Test>
struct exists
{
template<class U>
static std::true_type check(Test<U>*);
template<class U>
static std::false_type check(...);
static constexpr bool value = decltype(check<T>(0))::value;
};
template<class U, class = decltype(sum(std::declval<U>(), std::declval<U>()))>
struct sum_test{};
template <class T>
void validate_sum()
{
if constexpr (exists<T, sum_test>::value)
{
std::cout << "sum exists for type " << typeid(T).name() << '\n';
}
else
{
std::cout << "sum does not exist for type " << typeid(T).name() << '\n';
}
}
class A {};
class B {};
void sum(const A& l, const A& r); // we only need to declare the function, not define it
}
int main(int, const char**)
{
validate_sum<A>();
validate_sum<B>();
}
Here's the output using clang:
sum exists for type N12_GLOBAL__N_11AE
sum does not exist for type N12_GLOBAL__N_11BE
I should point out that weird things happened when I used an int instead of A (sum() has to be declared before sum_test for the exists to work, so maybe exists isn't the right name for this). Some kind of template expansion that didn't seem to cause problems when I used A. Gonna guess it's ADL-related.
This answer is for global functions, as a complement to the other answers on testing methods. This answer only applies to global functions.
First, provide a fallback dummy function in a separate namespace. Then determine the return type of the function-call, inside a template parameter. According to the return-type, determine if this is the fallback function or the wanted function.
If you are forbidden to add anything in the namespace of the function, such as the case for std::, then you should use ADL to find the right function in the test.
For example, std::reduce() is part of c++17, but early gcc compilers, which should support c++17, don't define std::reduce(). The following code can detect at compile-time whether or not std::reduce is declared. See it work correctly in both cases, in compile explorer.
#include <numeric>
namespace fallback
{
// fallback
std::false_type reduce(...) { return {}; }
// Depending on
// std::recuce(Iter from, Iter to) -> decltype(*from)
// we know that a call to std::reduce(T*, T*) returns T
template <typename T, typename Ret = decltype(reduce(std::declval<T*>(), std::declval<T*>()))>
using return_of_reduce = Ret;
// Note that due to ADL, std::reduce is called although we don't explicitly call std::reduce().
// This is critical, since we are not allowed to define any of the above inside std::
}
using has_reduce = fallback::return_of_reduce<std::true_type>;
// using has_sum = std::conditional_t<std::is_same_v<fallback::return_of_sum<std::true_type>,
// std::false_type>,
// std::false_type,
// std::true_type>;
#include <iterator>
int main()
{
if constexpr (has_reduce::value)
{
// must have those, so that the compile will find the fallback
// function if the correct one is undefined (even if it never
// generates this code).
using namespace std;
using namespace fallback;
int values[] = {1,2,3};
return reduce(std::begin(values), std::end(values));
}
return -1;
}
In cases, unlike the above example, when you can't control the return-type, you can use other methods, such as std::is_same and std::contitional.
For example, assume you want to test if function int sum(int, int) is declared in the current compilation unit. Create, in a similar fashion, test_sum_ns::return_of_sum. If the function exists, it will be int and std::false_type otherwise (or any other special type you like).
using has_sum = std::conditional_t<std::is_same_v<test_sum_ns::return_of_sum,
std::false_type>,
std::false_type,
std::true_type>;
Then you can use that type:
if constexpr (has_sum::value)
{
int result;
{
using namespace fallback; // limit this only to the call, if possible.
result = sum(1,2);
}
std::cout << "sum(1,2) = " << result << '\n';
}
NOTE: You must have to have using namespace, otherwise the compiler will not find the fallback function inside the if constexpr and will complain. In general, you should avoid using namespace since future changes in the symbols inside the namespace may break your code. In this case there is no other way around it, so at least limit it to the smallest scope possible, as in the above example