jez*_*zza 5 c++ polymorphism templates c++14
我想要如下设置:
template <typename T> class a {};
class b : public a<int> {};
template <typename T>
void do_foo(std::unique_ptr<a<T>> foo)
{
// Do something with foo
}
int main()
{
do_foo(std::make_unique<b>());
}
Run Code Online (Sandbox Code Playgroud)
这无法通过注释说template argument deduction/substitution failed和进行编译mismatched types 'a<T>' and 'b'。这是不言自明的。我可以通过编写 来帮助编译器do_foo<int>(std::make_unique<b>());,但是我通过编写int两次来重复自己。
在这种情况下,有没有办法让编译器推断出模板参数?你怎么称呼这种行为?我尝试搜索诸如“继承类型的模板类型推导”、“多态模板推导”等内容。
在这种情况下有没有办法让编译器推断出模板参数?
不,C++14(甚至 C++20)中没有。
您将这种行为称为什么?
符合标准。具体来说,本段适用:
[临时扣费电话]
4一般来说,推导过程会尝试找到模板参数值,使推导结果与(如上所述进行类型转换后)
A相同。但是,在三种情况下允许存在差异:AA
- 如果原始类型
P是引用类型,则推导的A(即引用所引用的类型)可以比转换后的 更符合 cv 条件A。- 转换后的对象
A可以是另一个指针或指向成员类型的指针,可以A通过限定转换 ([conv.qual]) 转换为推导的类型。- 如果
P是一个类并且具有simple-template-idP形式,则转换后的可以是推导的派生类。同样,如果是指向simple-template-id形式的类的指针 ,则转换后的可以是指向由推导的 所指向的派生类的指针。AAPAA
这是一个详尽的案例列表,其中模板参数可以从函数参数中有效推导,即使它与函数参数的模式不完全匹配。第一个和第二个项目符号处理诸如
template<class A1> void func(A1&){}
template<class A2> void func(A2*){}
int main() {
const int i = 1;
func(i); // A1 = const int
func(&i); // A2 = const int
}
Run Code Online (Sandbox Code Playgroud)
第三个项目符号是最接近我们的情况的。从模板特化派生的类可用于推导与其基类相关的模板参数。为什么它在你的情况下不起作用?因为函数模板参数是unique_ptr<a<T>>,而您调用它的参数是unique_ptr<b>。专业化本身unique_ptr并不通过继承相关。所以它们与项目符号不匹配,推论失败。
但这并不意味着像这样的包装器unique_ptr完全阻止模板参数推导。例如:
template <typename> struct A {};
struct B : A<int> {};
template<typename> struct wrapper{};
template<> struct wrapper<B> : wrapper<A<int>> {};
template<typename T>
void do_smth(wrapper<A<T>>) {}
int main() {
do_smth(wrapper<B>{});
}
Run Code Online (Sandbox Code Playgroud)
在本例中,wrapper<B>派生自wrapper<A<int>>. 所以第三条是适用的。并且通过模板参数推导的复杂(和递归)过程,它允许B匹配A<T>和推导T = int。
TL;DR:unique_ptr<T>专业化无法复制原始指针的行为。它们不继承unique_ptroverT的基础的专业化。也许如果反射出现在 C++ 中,我们将能够对一个具有这种行为方式的智能指针进行元编程。
| 归档时间: |
|
| 查看次数: |
98 次 |
| 最近记录: |