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 imgs).

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?

0

There are 0 best solutions below