简体   繁体   中英

C++ How to overload a function which gets as parameter an iterator of different templated objects?

I have two similar generic classes - MyClass1 and MyClass2. I want the function "func" to iterate over the elements of MyClass1 and/or MyClass1 objects.

but I get the folowing error:

'auto' in return type deduced as 'Group3d<MyClass1<5> >' here but deduced as 'Group2d<MyClass1<5> >' in earlier return statement
        return funcForClass2<T>(start, end);
        ^

I can't figure out how to overload this function, since the type is deduced after calling it.

Any advice?

main.cpp:

int main() {
    list<MyClass1<5>> a = {{0}, {-5}};
    auto res5 = func(a.begin(), a.end());

    list<MyClass2<6>> b = {{0, 3}, {0, -2}};
    auto res6 = func(b.begin(), b.end());
}

utils.h:

template<typename T>
using deref_iter_t = std::remove_reference_t<decltype(*std::declval<T>())>;

template<class Iterator>
auto func(Iterator start, Iterator end) {
    int dim;

    using T = deref_iter_t<Iterator>;

    dim = (start)->getDim();
    if (dim == 2) { // MyClass1 objects
        return funcForClass1<T>(start, end);
    }
    if (dim == 3) { // MyClass2 objects
        return funcForClass2<T>(start, end);
    }
}

Assuming dim() is constexpr, you can do it with overload resolution. Slightly simplifying the example to show relevant parts:

#include <utility>

struct A {
    static constexpr int x = 1;
};

struct B {
    static constexpr int x = 2;
};

int impl(std::integral_constant<int, 1> ) {
    return {};
}

char* impl(std::integral_constant<int, 2> ) {
    return {};
}


template<class T> auto foo(T t) {
    return impl(std::integral_constant<int, T::x>{});
}

int main() {
    auto f1 = foo(A{});
    auto f2 = foo(B{});
}

Write your functions as

template<size_t I> 
auto func(
  const typename list<MyClass1<I>>::iterator& begin, 
  const typename list<MyClass1<I>>::iterator& end)
{ 
// do something
}

template<size_t I> 
auto func(
  const typename list<MyClass2<I>>::iterator& begin, 
  const typename list<MyClass2<I>>::iterator& end)
{
// do something else 
}

For your deref_iter_t , is seems you could have used std::iterator_traits<Iterator>::value_type instead, anyway no longer used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM