Reputation: 2982
I have the following use case:
template<typename T>
struct Foo
{
bool setValue(T const &iValue)
{
if(fValue != iValue)
{
fValue = iValue;
return true;
}
return false;
}
T fValue;
};
which works only as long as T
provides a operator!=
implementation (and I suppose one of the complication is that operator!=
can be implemented as member function of T
or not...).
Ideally I would like to write something like this using C++ 17 if constexpr
syntax
template<typename T>
struct Foo
{
bool setValue(T const &iValue)
{
if constexpr (is_diff_operator_defined<T>::value) {
if(fValue != iValue)
{
fValue = iValue;
return true;
}
} else {
fValue = iValue;
return true;
}
return false;
}
T fValue;
};
How would I go about it? Please note I am using C++ 17 so would prefer a solution that uses the latest and greatest feature (likes if constexpr
which makes the code a lot easier to read/comprehend than optional dummy template function parameters we usually see with sfinae...)
Upvotes: 1
Views: 122
Reputation: 41780
With the detection idiom it's quite simple to do:
template<typename T>
using operator_not_eq_t = decltype(std::declval<T const&>() != std::declval<T const&>());
template<typename T>
constexpr auto is_diff_operator_defined = is_detected_v<operator_not_eq_t, T>;
Then simply use it with if constexpr
as you wrote. (minus ::value
)
Note that with concepts you can simply do that inline:
if constexpr (requires { fValue != iValue; }) {
if (fValue != iValue) {
// ...
}
}
Upvotes: 1