I have a class that I use to apply functions to each element in a vector representing an image.
template <typename T, typename E>
class func1_img_expr_t : public img_expr_t<T> {
public:
std::function<T(typename E::value_type)> f;
E e;
int size, w, h, d;
func1_img_expr_t(std::function<T(typename E::value_type)> f, const E& e)
: f(f), e(e), size(e.size), w(e.w), h(e.h), d(e.d) {
}
T operator[](int i) const {
return f(e[i]);
}
template <typename E2>
bool similar(const E2& o) const {
return e.similar(o);
}
};
Each function is then defined like this:
template <typename E>
auto ceil(const E& e) {
return func1_img_expr_t<decltype(call(std::declval<typename decltype(to_expr(e))::value_type>())),
decltype(to_expr(e))>(
[](auto e) { return std::ceil(e); }, to_expr(e));
}
My image type is called img
and is templatized so I can have img<float>
, img<double>
etc., so I can have img<T> foo
and call std::ceil(foo);
and it will return std::ceil()
for every element in the image.
My problem is that elsewhere in the code I have lines such as:
int Lx = std::ceil((nx-1)/2);
(where nx is of type int
). This results in a compiler error that the call of the overloaded ceil(int)
is ambiguous. I can see why, because if typename E
== int
then the above is a valid candidate, but obviously it's unnecessary.
The usual advice on eliminating this kind of error (see [here]https://www.geeksforgeeks.org/error-call-of-overloaded-functionx-is-ambiguous-ambiguity-in-function-overloading-in-c/ for example is to typecast the variable (I don't think that would work here as nx
is already an int
, the issue is that the overloaded call is valid for int
) or to remove either one of the functions (well I can't remove std::ceil
, and I can't remove my function otherwise I lose the ability to apply it to img
s).
Is there a way (maybe using std::enable_if?) of limiting the applicability of my func1_img_expr_t so that it will only work when passed an img
?