In a generic function I use the following idiom
template<class It1, class It2>
void do_something(It1 first, It1 second, It2 d_first){
using std::copy;
copy(first, second, d_first);
}
Now suppose I have several iterator in my namespace N
.
namespace N{
struct itA{using trait = void;};
struct itB{using trait = void;};
struct itC{using trait = void;};
}
An I want to overload copy for these iterators in this namespace. Naturally I would do:
namespace N{
template<class SomeN1, class SomeN2>
SomeN2 copy(SomeN1 first, SomeN1 last, SomeN2 d_first){
std::cout << "here" << std::endl;
}
}
However when I call do_something
with N::A
, N::B
or N::C
argument I get "ambiguous call to copy" even though these are in the same namespace as N::copy
.
Is there a way to win over std::copy
in the context of the original function above?
I though that if I put constrains over the template arguments then N::copy
would be preferred.
namespace N{
template<class SomeN1, class SomeN2, typename = typename SomeN1::trait>
SomeN2 copy(SomeN1 first, SomeN1 last, SomeN2 d_first){
std::cout << "here" << std::endl;
}
}
but it doesn't help.
What other workarounds can I try for the generic call to copy to prefer to a copy in the namespace of arguments rather than std::copy
.
Complete code:
#include<iostream>
#include<algorithm>
namespace N{
struct A{};
struct B{};
struct C{};
}
namespace N{
template<class SomeN1, class SomeN2>
SomeN2 copy(SomeN1 first, SomeN1 last, SomeN2 d_first){
std::cout << "here" << std::endl;
}
}
template<class It1, class It2>
void do_something(It1 first, It1 second, It2 d_first){
using std::copy;
copy(first, second, d_first); // ambiguous call when It is from namespace N (both `std::copy` and `N::copy` could work.
}
int main(){
N::A a1, a2, a3;
do_something(a1, a2, a3);
}
A typical error message is
error: call of overloaded ‘copy(N::A&, N::A&, N::A&)’ is ambiguous
Aucun commentaire:
Enregistrer un commentaire