具有默认模板参数的多态类的模板推导失败

时间:2018-11-06 10:55:40

标签: c++ polymorphism default-parameters template-deduction

考虑以下示例:

#include <memory>

template<typename T>
class A {};

template<typename T1, typename T2>
class B: public A<T1> {};

template<typename T = int>
void foo(std::shared_ptr< A<T> > test)
{

}

int main()
{
    auto p = std::make_shared<B<int, int>>();
    foo<int>(p);    // Works
    foo<>(p);       // Does not work
    foo(p);         // Does not work
}

我试图在不为foo明确指定类型T的情况下进行编译,但这是行不通的。我不确定为什么好像我显式地键入T一样好,但是即使我告诉了编译器,如果我不告诉我类型T应该是什么,它也不会编译。明确指定它。

我明白了为什么编译器不能推断出类型T,但是为什么当我不指定类型T时却不能使用默认类型T?我该如何解决这个问题?这样做的“正确”方法是什么?

1 个答案:

答案 0 :(得分:2)

该问题与默认模板参数无关。相反,pstd::shared_ptr<B<int, int>>)的类型不能与模板std::shared_ptr<T>的{​​{1}}自变量匹配:在模板自变量推导期间,不考虑任何转换,并将对派生类实例的引用作为基类引用传递确实是一种转换。

您可以通过显式上载foo管理的指针来解决此问题。

std::shared_ptr

现在,这些调用将按预期进行:

std::shared_ptr<A<int>> p = std::make_shared<B<int, int>>();

请注意,模板参数类型是否出现在功能模板的参数列表中(可以推论)有很大的不同。考虑这两个模板,

foo<>(p); // Ok, argument matches the signature
foo(p);   // Same...

两者的默认类型均为template <class T = int> void foo(T&&) { std::cout << __PRETTY_FUNCTION__ << "\n"; } template <class T = int> void bar(double) { std::cout << __PRETTY_FUNCTION__ << "\n"; } ,但是当它们被实例化时

int

第一个实例化使用函数参数推导出模板参数(结果为foo<>(0.0); // outputs: void foo(T&&) [with T = double] bar<>(0.0); // outputs: void bar(double) [with T = int] ),而第二个实例不推导任何内容,默认为double