有没有办法在C++中隐式匹配嵌套模板类型?

Dim*_*ann 9 c++ templates

我有以下MWE:

#include <iostream>
#include <memory>

class A {
public:
    int n = 42;
    typedef std::shared_ptr<A> Ptr;
};

template<typename T>
void foo(typename T::Ptr arg) {
    std::cout << arg->n << std::endl;
}

template<typename T>
void bar(T arg) {
    std::cout << arg.n << std::endl;
}

int main() {
    A::Ptr a = A::Ptr(new A());
    foo<A>(a); // Can I avoid giving <A> here explicitly.
    // foo(a); // does not compile
    bar(*a); // after all this does work
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

对我来说,看起来也应该可以打电话foo(a)而不是foo<A>(a).为什么这是不可能的,我可以以某种方式改变定义,foo使这成为可能吗?

我意识到我可以跳过::Ptr签名,但我仍然想要访问A没有指针的类型.

Naw*_*waz 7

这是不可能的,因为那是不可导出的背景.

类型a只是std::shared_ptr<A>,这意味着如果 foo(a)有效,那么以下应该有效:

std::shared_ptr<A> x(new A());
foo(x);
Run Code Online (Sandbox Code Playgroud)

如果是这样,那么应该T推断出什么?为什么?你可能会想说" T应该推断出来A,因为它A有一个与之Ptr相同的嵌套类型std::shared_ptr<A> ".那么,如果有另一个类定义为:

struct B
{
    typedef std::shared_ptr<A> Ptr;
};
Run Code Online (Sandbox Code Playgroud)

应该T推断出什么?A还是B?或者是其他东西?

以下是使用不同示例讨论不可导入上下文的另一个主题:

希望有所帮助.

  • @Ven简而言之,只要编译器没有理智的方法来推断出存在极端情况和无限类型和值的情况下仍保持理智的参数,它就适用.有关更正式的处理,请参阅C++标准的第14章. (3认同)