Date: Sat, 17 Sep 2022 21:58:34 +0100
When we have a 'variant' object such as either of the following two:
variant< LaserController, DrillController > obj;
variant< monostate, LaserController, DrillController > obj;
It would be nice if the following statement:
int error_code = obj->Initialise(5, 2.0);
could be treated by the compiler as though we had actually written:
int error_code =
std::visit([&obj]<class U>(U &u)
{
if constexpr ( std::same_as<U, std::monostate> )
{
throw std::bad_variant_access();
// The following line never gets executed -- we just
// have it here to give this lambda function the correct
// return type when U is 'std::monostate'
return std::get<1u>(obj).Initialise(5, 2.0);
}
else
{
return u.Initialise(5, 2.0);
}
}, obj);
The GNU compiler already has some compile-time checking in place to
make sure that "LaserController::Initialise" and
"DrillController::Initialise" have the same return type. Here's the
output I got from the g++ compiler when I changed the return type of
"DrillController::Initialise":
error: static assertion failed: std::visit requires the
visitor to have the same return type for all alternatives of a variant
I've tried messing around with the preprocessor to write a macro to
perform the translation I've written above, but I couldn't pull it
off. I think we would need compiler support for this one.
In the following code snippet, I've introduced a new function
attribute called 'translate', along with a new keyword called
'__translate__'. When you have expression such as the following:
obj->Method(arg1,arg2,arg3);
, the keyword '__translate__' gets substituted with "Method(arg1,arg2,arg3)".
So the definition of "std::variant" would look something like as follows:
namespace std {
class variant {
public:
[[translate]] auto operator->
{
return std::visit([this]<class U>(U &u)
{
if constexpr ( std::same_as<U, std::monostate> )
{
throw std::bad_variant_access();
// The following line never gets executed -- we just
// have it here to give this lambda function the correct
// return type when U is 'std::monostate'
return std::get<1u>(*this). __translate__ ;
}
else
{
return u. __translate__ ;
}
}, obj);
}
};
}
variant< LaserController, DrillController > obj;
variant< monostate, LaserController, DrillController > obj;
It would be nice if the following statement:
int error_code = obj->Initialise(5, 2.0);
could be treated by the compiler as though we had actually written:
int error_code =
std::visit([&obj]<class U>(U &u)
{
if constexpr ( std::same_as<U, std::monostate> )
{
throw std::bad_variant_access();
// The following line never gets executed -- we just
// have it here to give this lambda function the correct
// return type when U is 'std::monostate'
return std::get<1u>(obj).Initialise(5, 2.0);
}
else
{
return u.Initialise(5, 2.0);
}
}, obj);
The GNU compiler already has some compile-time checking in place to
make sure that "LaserController::Initialise" and
"DrillController::Initialise" have the same return type. Here's the
output I got from the g++ compiler when I changed the return type of
"DrillController::Initialise":
error: static assertion failed: std::visit requires the
visitor to have the same return type for all alternatives of a variant
I've tried messing around with the preprocessor to write a macro to
perform the translation I've written above, but I couldn't pull it
off. I think we would need compiler support for this one.
In the following code snippet, I've introduced a new function
attribute called 'translate', along with a new keyword called
'__translate__'. When you have expression such as the following:
obj->Method(arg1,arg2,arg3);
, the keyword '__translate__' gets substituted with "Method(arg1,arg2,arg3)".
So the definition of "std::variant" would look something like as follows:
namespace std {
class variant {
public:
[[translate]] auto operator->
{
return std::visit([this]<class U>(U &u)
{
if constexpr ( std::same_as<U, std::monostate> )
{
throw std::bad_variant_access();
// The following line never gets executed -- we just
// have it here to give this lambda function the correct
// return type when U is 'std::monostate'
return std::get<1u>(*this). __translate__ ;
}
else
{
return u. __translate__ ;
}
}, obj);
}
};
}
Received on 2022-09-17 20:58:45