【发布时间】:2019-06-21 09:11:39
【问题描述】:
在一个通用函数中,我使用以下成语,
template<class It1, class It2>
void do_something(It1 first, It1 second, It2 d_first){
... other stuff here...
using std::copy;
copy(first, second, d_first);
}
do_something 是一个通用函数,它不应该知道任何其他库的任何具体信息(可能std:: 除外)。
现在假设我的命名空间 N 中有几个迭代器。
namespace N{
struct itA{using trait = void;};
struct itB{using trait = void;};
struct itC{using trait = void;};
}
我想在这个命名空间中为这些迭代器重载副本。 我自然会这样做:
namespace N{
template<class SomeN1, class SomeN2>
SomeN2 copy(SomeN1 first, SomeN1 last, SomeN2 d_first){
std::cout << "here" << std::endl;
}
}
但是,当我使用 N::A、N::B 或 N::C 参数调用 do_something 时,即使它们与 N::copy 在同一个命名空间中,我也会收到“模糊的复制调用”。
有没有办法在上面原函数的上下文中战胜std::copy?
我认为,如果我对模板参数施加约束,那么N::copy 将是首选。
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;
}
}
但这无济于事。
我可以尝试哪些其他解决方法来让通用调用 copy 更喜欢参数命名空间中的副本而不是 std::copy。
完整代码:
#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);
}
一个典型的错误信息是
error: call of overloaded ‘copy(N::A&, N::A&, N::A&)’ is ambiguous
我是否认为 C++ 概念会通过更喜欢具有更多约束而不是更少约束的函数调用来提供帮助?
【问题讨论】:
-
不是骗子,而是related。
-
显然错误来自总是在做
using std::copy;。 -
@alfC 您的
N::copy也是一个函数模板,它没有与命名空间N关联的参数。因此,就重载解决而言,它并不比std::copy好。 -
@MatthieuBrucher,如果我使用
std::copy,那么就不可能调用copy的特殊版本。唯一的方法是重载std::copy(在命名空间std中),我不知道是否允许。 -
@geza,问题是
do_something是一个模板函数,不知道命名空间N或库N。
标签: c++ c++11 ambiguous argument-dependent-lookup