I have such code:
boost::optional<double> result = _ind1.Value() / _ind2.Value();
Each arg is boost::optional<double> too:
boost::optional<double> Value() {
return value;
}
Errors are:
Error 1 error C2676: binary '/' : 'boost::optional<T>' does not define this operator or a conversion to a type acceptable to the predefined operator
2 IntelliSense: no operator "/" matches these operands
operand types are: boost::optional<double> / boost::optional<double>
I understand that it seems that division is just not defined. I expect result to be boost::none if any of two arguments is none - otherwise I want it to be normal double division. Should I just write this myself?
Of course such a simple operation as division of doubles is supported.
But you aren't trying to divide doubles. You're trying to divide boost::optional<double>s which is a whole different story.
If you want, you can define a division operator for this. It might look like (untested):
template<typename T>
boost::optional<T> operator/(const boost::optional<T>& a, const boost::optional<T>& b)
{
if(a && b) return *a / *b;
else return boost::optional<T>();
}
In C++11 (code courtesy of Yakk):
template<class T,class U> struct divide_result {
typedef typename std::decay<decltype(std::declval<T>()/std::declval<U>())>::type;
};
template<class T, class U> using divide_result_t=typename divide_result<T,U>::type;
template<typename T,typename U>
boost::optional<divide_result_t<T,U>> operator/(const boost::optional<T>& a, const boost::optional<U>& b)
{
if(a && b) return *a / *b;
else return boost::none;
}
I used a template because now it's also good for int, float, etc.
Related
In a project I'm working on I have a templated function similar to this where all of the arguments should be of type T
#include <iostream>
template<typename T> bool aWithinBOfC(T a, T b, T c)
{
return std::abs(a - c) < b;
}
the issue I'm having is it won't compile if all of the arguments are not of the same type but it seems reasonable that it should implicitly cast similar types to the one with the highest resolution before evaluation. Is there any way to get a call like this to be valid?
int main()
{
double a{1.2};
double b{1.4};
float c{0.1f};
std::cout << aWithinBOfC(a, b, c) << std::endl;
}
Something along these lines, perhaps:
template<typename T>
bool aWithinBOfCImpl(T a, T b, T c) {
/* actual implemenattion */
}
template <typename ... Args>
auto aWithinBOfC(Args... args) {
return aWithinBOfCImpl<std::common_type_t<Args...>>(args...);
}
Demo
You don’t need implicit conversions at the call site. The compiler will implicitly convert the types to the largest one in the expression in the return statement.
template <class T, class U, class V>
bool aWithinBOfC(T a, U b, V c) {
return std::abs(a - c) < b;
}
I want to multiplay a std::complex<T> by a double, assuming that T operator*(const T &t, double d) is defined. Since I need to do this for 3 different types T, i tried to write a template function for the operator. Here's an example with T=float.
#include <iostream>
#include <complex>
template <typename T>
std::complex<T> operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
int main() {
std::complex<float> cf(1.0, 1.0);
std::complex<double> cd(1.0, 1.0);
double d = 2.0;
std::cout << cf * d << std::endl;
std::cout << cd * d << std::endl;
}
This gives the compiler error
error: ambiguous overload for ‘operator*’ (operand types are ‘std::complex<double>’ and ‘double’)
The reason is clear, since for T=double my overload clashes with the implementation in <complex>. First casting the right hand side to a T (i.e. cf * float(d) in the example above) is not an option, since that would introduce significant overhead for some of my datatypes.
Is there any way I can tell the compiler that it should ignore my overload for T=double?
Is there any way I can tell the compiler that it should ignore my overload for T=double?
You might use SFINAE:
template <typename T>
std::enable_if_t<!std::is_same<double, T>::value, std::complex<T>>
operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
but your implementation is not coherent with regular operator*.
A safer way would be to introduce your own type to wrap double, something like:
struct MyWrapper { double d; };
template <typename T>
std::complex<T> operator*(const std::complex<T> &cd, MyWrapper d) {
return std::complex<T>(cd.real() * d.d, cd.imag());
}
std::complex already defines an operator * in the form of
template< class T >
std::complex<T> operator*( const std::complex<T>& lhs, const T& rhs);
This conflicts with your own operator * since both functions resolve to taking a std::complex<double> and a double.
That means you really only need to define an operator * for std::vector<float> and a double so you can change your overload to
std::complex<float> operator*(const std::complex<float> &cd, double d) {
return std::complex<float>(cd.real() * d, cd.imag());
}
And then
std::cout << cf * d << std::endl;
std::cout << cd * d << std::endl;
will work.
If you want to keep the overload a template function you can use SFINAE to make it not compile for the case when you have a std::complex<double> by using
template <typename T, std::enable_if_t<!std::is_same_v<double, T>, bool> = true>
std::complex<T> operator*(const std::complex<T> &cd, double d) {
return std::complex<T>(cd.real() * d, cd.imag());
}
Consider the following function that computes the integral or floating-point modulo depending on the argument type, at compile-time:
template<typename T>
constexpr T modulo(const T x, const T y)
{
return (std::is_floating_point<T>::value) ? (x < T() ? T(-1) : T(1))*((x < T() ? -x : x)-static_cast<long long int>((x/y < T() ? -x/y : x/y))*(y < T() ? -y : y))
: (static_cast<typename std::conditional<std::is_floating_point<T>::value, int, T>::type>(x)
%static_cast<typename std::conditional<std::is_floating_point<T>::value, int, T>::type>(y));
}
Can the body of this function be improved ? (I need to have a single function for both integer and floating-point types).
Here's one way to clean this up:
#include <type_traits>
#include <cmath>
template <typename T> // integral? floating point?
bool remainder_impl(T a, T b, std::true_type, std::false_type) constexpr
{
return a % b; // or whatever
}
template <typename T> // integral? floating point?
bool remainder_impl(T a, T b, std::false_type, std::true_type) constexpr
{
return std::fmod(a, b); // or substitute your own expression
}
template <typename T>
bool remainder(T a, T b) constexpr
{
return remainder_impl<T>(a, b,
std::is_integral<T>(), std::is_floating_point<T>());
}
If you try and call this function on a type that's not arithmetic, you'll get a compiler error.
I would rather define it this way (template aliases + template overloading):
#include <type_traits>
using namespace std;
// For floating point types
template<typename T, typename enable_if<is_floating_point<T>::value>::type* p = nullptr>
constexpr T modulo(const T x, const T y)
{
return (x < T() ? T(-1) : T(1)) * (
(x < T() ? -x : x) -
static_cast<long long int>((x/y < T() ? -x/y : x/y)) * (y < T() ? -y : y)
);
}
// For non-floating point types
template<typename T>
using TypeToCast = typename conditional<is_floating_point<T>::value, int, T>::type;
template<typename T, typename enable_if<!is_floating_point<T>::value>::type* p = nullptr>
constexpr T modulo(const T x, const T y)
{
return (static_cast<TypeToCast<T>>(x) % static_cast<TypeToCast<T>>(y));
}
int main()
{
constexpr int x = modulo(7.0, 3.0);
static_assert((x == 1.0), "Error!");
return 0;
}
It is lengthier but cleaner IMO. I am assuming that by "single function" you mean "something that can be invoked uniformly". If you mean "a single function template", then I would just keep the template alias improvement and leave the overload. But then, as mentioned in another answer, it would not be clear why you do need to have one single function template.
You ask,
“Can the body of this function be improved?”
Certainly. Right now it is a spaghetti mess:
template<typename T>
constexpr T modulo(const T x, const T y)
{
return (std::is_floating_point<T>::value) ? (x < T() ? T(-1) : T(1))*((x < T() ? -x : x)-static_cast<long long int>((x/y < T() ? -x/y : x/y))*(y < T() ? -y : y))
: (static_cast<typename std::conditional<std::is_floating_point<T>::value, int, T>::type>(x)
%static_cast<typename std::conditional<std::is_floating_point<T>::value, int, T>::type>(y));
}
You clarify that …
“(I need to have a single function for both integer and floating-point types)”
Well the template is not a single function. It’s a template. Functions are generated from it.
This means your question builds on a false assumption.
With that assumption removed, one way to simplify the function body, which you should do as a matter of course, is to specialize the template for floating point types versus other numeric types. To do that put the function template implementation in a class (because C++ does not support partial specialization of functions, only of classes).
Then you can employ various formatting tricks, including the "0?0 : blah" trick to make the function more readable, with lines and indentation and stuff! :-)
Addendum: delving into your code I see that you cast haphazardly to long int and int with disregard of the invoker's types. That's ungood. It is probably a good idea to write up a bunch of automated test cases, invoking the function with various argument types and big/small values.
template <class T>
constexpr
T
modulo(T x, T y)
{
typedef typename std::conditional<std::is_floating_point<T>::value,
int,
T
>::type Int;
return std::is_floating_point<T>() ?
x - static_cast<long long>(x / y) * y :
static_cast<Int>(x) % static_cast<Int>(y);
}
I believe there is simpler:
// Special available `%`
template <typename T, typename U>
constexpr auto modulo(T const& x, U const& y) -> decltype(x % y) {
return x % y;
}
Note: based on detection of % so also works for custom types as long as they implement the operator. I also made it mixed type while I was at it.
// Special floating point
inline constexpr float modulo(float x, float y) { return /*something*/; }
inline constexpr double modulo(double x, double y) { return /*something*/; }
inline constexpr long double modulo(long double x, long double y) { return /*something*/; }
Note: it would cleaner to have fmod available unfortunately I do not believe it is constexpr; therefore I chose to have non-template modulos for the floating point types which allows you to perform magic to compute the exact modulo possibly based on the binary representation of the type.
You can do that much simpler if you want:
template<typename A, typename B>
constexpr auto Modulo(const A& a, const B& b) -> decltype(a - (b * int(a/b)))
{
return a - (b * int(a/b));
}
For some strange reason, I can't get the template arguments in this one piece of code to implicitly cast to a compatible type.
#include <type_traits>
template <typename T, unsigned D>
struct vec;
template <>
struct vec<float, 2> {
typedef float scalar;
static constexpr unsigned dimension = 2;
float x, y;
float& operator[] (unsigned i) { return (&x)[i]; }
float const& operator[] (unsigned i) const { return (&x)[i]; }
};
template <typename L, typename R>
struct add;
template <typename L, typename R, unsigned D>
struct add<vec<L, D>, vec<R, D>> {
typedef vec<L, D> left_type;
typedef vec<R, D> right_type;
typedef vec<typename std::common_type<L, R>::type, D> return_type;
add(left_type l, right_type r)
: left(l),
right(r)
{}
operator return_type() const
{
return_type result;
for (unsigned i = 0; i < D; ++i)
result[i] = left[i] + right[i];
return result;
}
left_type left;
right_type right;
};
template <typename L, typename R, unsigned D>
add<vec<L, D>, vec<R, D>>
operator+(vec<L, D> const& lhs, vec<R, D> const& rhs)
{
return {lhs, rhs};
}
int main()
{
vec<float, 2> a, b, c;
vec<float, 2> result = a + b + c;
}
Fails with:
prog.cpp: In function 'int main()':
prog.cpp:55:36: error: no match for 'operator+' in 'operator+ [with L = float, R = float, unsigned int D = 2u](((const vec<float, 2u>&)((const vec<float, 2u>*)(& a))), ((const vec<float, 2u>&)((const vec<float, 2u>*)(& b)))) + c'
So if I'm correct, the compiler should see the code in the main function as this:
((a + b) + c)
compute a + b
cast the result of a + b from add<...> to vec<float, 2> using the conversion operator in add<...>
compute (a + b) + c
But it never does the implicit cast. If I explicitly cast the result of (a + b) to a vec, the code works fine.
I'm going to side-step your actual problem and instead make a recommendation: Rather than writing all of this complicated boilerplate from scratch, have a look at Boost.Proto, which has taken care of all the tricky details for you:
Proto is a framework for building Domain Specific Embedded Languages in C++. It provides tools for constructing, type-checking, transforming and executing expression templates. More specifically, Proto provides:
An expression tree data structure.
A mechanism for giving expressions additional behaviors and members.
Operator overloads for building the tree from an expression.
Utilities for defining the grammar to which an expression must conform.
An extensible mechanism for immediately executing an expression template.
An extensible set of tree transformations to apply to expression trees.
See also the library author's Expressive C++ series of articles, which more-or-less serve as an (excellent) in-depth Boost.Proto tutorial.
Most conversions are not used during template argument deduction.
You rely on template argument deduction when you call your operator+ overload: it is only callable where both arguments are of type vec<...>, but when you try to call it the left-hand argument is of type add<...>. The compiler is not able to figure out that you really mean for that overload to be called (and it isn't allowed to guess), hence the error.
I am working on making an expression class:
template<typename T, typename U>
class expression
{
public:
expression(T vala, U valb, oper o){val1 = vala; val2 = valb; op = o;}
operator bool{return(val1 op val2);}
private:
T val1;
U val2;
oper op;
};
as you can see, this is somewhat pseudocode, because I need an operator class. My original thought was to create an array of all possible operators, and then convert it through a string, but that wouldn't work because of the sheer number of operators, and how to convert it to a string except through a two dimensional array, where n[0][0] has the first operator, and n[0][1] has that operators string.
Does anybody have any suggestions to adding an operator value to my expression class?
Similar methods are used in c++ expression templates techniqueue.
You create expression as a class with a method such as apply or evaluate. This method takes the parameters and applies the expression.
Have a look what expression templates are using.
http://www.angelikalanger.com/Articles/Cuj/ExpressionTemplates/ExpressionTemplates.htm
https://www.cct.lsu.edu/~hkaiser/spring_2012/files/ExpressionTemplates-ToddVeldhuizen.pdf
As an example in your case:
struct isEqual
{
template <typename T, typename U>
bool operator()(T a, U b)
{
return a == b;
}
};
template <typename T, typename OP>
struct expression
{
T& a;
T& b;
OP& op;
expression(T a, T b, OP op) : a(a), b(b), op(op) {}
void eval() { op(a,b); }
};
int main()
{
expression<int, isEqual> exp(1,2,isEqual());
exp.eval();
}
Maybe a function pointer. Instead of ...
operator bool{return(val1 op val2);}
... code it as ...
operator bool{return op(val1, val2);}
... in which case op can be a pointer to a (any) function which takes two parameters and which returns bool.
template<typename T, typename U>
class expression
{
public:
//define pointer-to-function type
typedef bool *oper(const T& val1, const U& val2);
... etc ...
I'm not entirely sure what you're asking, but if you are trying to overload an arbitrary string as an operator, you can't. There is a finite set of operators that you can overload in c++
see here: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B
What you should do is overload operator() in oper to create a function object and return op(val1, val2) instead.
You can use the functional standard library and take your argument as a:
std::tr1::function<bool (T,U)>
ie:
#include <functional>
template<typename T, typename U>
class expression
{
public:
expression(T vala, U valb, oper o) : val1(vala), val2(valb), op(o)
{ }
operator bool{return op(val1, val2);}
private:
T val1;
U val2;
std::tr1::function<bool (T,U)> op;
};
Then, to create a expression:
#include <functional>
expression<int, int> foo(4,3, std::tr1::bind(greater()));
Here's a tutorial