I am writing a macro that when used to wrap a function call like so: macro(function())
, returns a std::optional<T>
, where T is the return value of the function. So far it works, but I run into problems when trying to get it to return a std::optional<bool>
when the function has no return type (i.e. it returns void).
The core of the problem is that the compiler tries to evaluate the scope of a if-constexpr that evaluates to false when the function has no return type.
I tried using two if-constexprs and one with an else. I tried inlining everything and spreading it out a few lines. I tried replacing the compiler-calculated constexpr constants with constant literals. Nothing works so far.
The macro as I have it now looks like this:
#ifndef troy
#define troy(body)[](){\
constexpr auto inner_type_is_void=std::is_same<decltype(body), void>::value;\
using inner_type=std::conditional<inner_type_is_void,bool,decltype(body)>::type;\
try{\
if constexpr (inner_type_is_void) {(body); return std::optional<inner_type>{true};}\
if constexpr (!inner_type_is_void) {return std::optional<inner_type>{(body)};}\
} catch (...){\
return std::optional<inner_type>{};\
}\
}()
#endif
And I use it like so:
{
auto a=troy(f());
if (!a){
std::cout << "fail" << std::endl;
} else{
std::cout << "success: " << *a << std::endl;
}
}
It works when f returns a value, but gives a compiler error when not. This compiler error is: no matching function for call to ‘std::optional<bool>::optional(<brace-enclosed initializer list>)’
on the line where the if-constexpr evaluates to false.