功能是模糊的,不是

Via*_*uct 8 c++ templates

xxx is ambiguous在处理我的c ++项目时得到了.由于整个项目太大而无法在这里上传,我做了一个简单的例子,弹出相同的错误信息.

#include <string>
#include <memory>

namespace a {

template <typename T, typename Target>
inline std::shared_ptr<T> getShared(Target const& t)
{
    return std::static_pointer_cast<T>(t->shared_from_this());
}

class A : public std::enable_shared_from_this<A>
{
};

}

namespace b {

template <typename T, typename Target>
inline std::shared_ptr<T> getShared(Target const& t)
{
    return std::static_pointer_cast<T>(t->shared_from_this());
}

class A : public std::enable_shared_from_this<A>
{
};

void invoke()
{
    // ERROR OCCURED!!!
    a::A* a;
    getShared<a::A>(a);

    // But this is compiled without any problem :(
    //  A* a;
    //  getShared<A>(a);
}

}

int main(int, char**)
{
    b::invoke();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是错误信息......

clang++ -c -pipe -g -std=gnu++1y -Wall -W -fPIC -DQT_QML_DEBUG -I../untitled -I. -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-clang -o main.o ../untitled/main.cpp
../untitled/main.cpp:34:2: error: call to 'getShared' is ambiguous
        getShared<a::A>(a);
        ^~~~~~~~~~~~~~~
../untitled/main.cpp:7:27: note: candidate function [with T = a::A, Target = a::A *]
inline std::shared_ptr<T> getShared(Target const& t)
                          ^
../untitled/main.cpp:21:27: note: candidate function [with T = a::A, Target = a::A *]
inline std::shared_ptr<T> getShared(Target const& t)
Run Code Online (Sandbox Code Playgroud)

我尝试了gcc 6.3.0和clang 3.8.1-24,两个编译器都给了我同样的错误.

有人能告诉我这段代码有什么问题吗?

MSa*_*ers 7

评论基本上回答了这个问题,但让我们把它全部包起来.

编译器的第一个挑战是解析getShared<a::A>(a);.现在,这可能是operator<operator>,但是编译器首先查找 getShared并注意到这是一个模板,所以<a::A>是模板参数列表.

它也是一个函数模板,a函数参数也是如此.此时,发生了一些复杂的事情.由于a具有类型a::A*,因此它具有关联的命名空间.编译器执行新的名称查找getShared,现在它知道它是带有参数和关联命名空间的函数.这第二个查询也发现a::getShared.这也是一个函数模板,它可以用实例化<a::A>.(SFINAE可以排除它,但争论还可以).

您现在有两个实例,重载解析不能解决它们的歧义.

如miradulo所述,第二次查找的名称是Argument Dependent Lookup.