Overload resolution and shared pointers to const(重载解析和指向常量的共享指针)
问题描述
我正在转换一个大型代码,以使用定制的共享指针而不是原始指针。我对超载解决方案有问题。考虑这个例子:
#include <iostream>
struct A {};
struct B : public A {};
void f(const A*)
{
std::cout << "const version
";
}
void f(A*)
{
std::cout << "non-const version
";
}
int main(int, char**)
{
B* b;
f(b);
}
此代码正确写入"非常数版本",因为qualification conversions在隐式转换序列的排名中起作用。现在看一下使用SHARED_PTR:的版本
#include <iostream>
#include<memory>
struct A {};
struct B : public A {};
void f(std::shared_ptr<const A>)
{
std::cout << "const version
";
}
void f(std::shared_ptr<A>)
{
std::cout << "non-const version
";
}
int main(int, char**)
{
std::shared_ptr<B> b;
f(b);
}
此代码无法编译,因为函数调用不明确。
我知道user-defined deduction-guide将是解决方案,但它仍然不存在于Visual Studio中。
我使用regexp转换代码,因为有数千个这样的调用。Regexp无法区分与常量版本匹配的调用和与非常量版本匹配的调用。是否有可能在使用共享指针时对重载解析进行更精细的控制,并避免手动更改每个调用?当然,我可以.get()原始指针并在调用中使用它,但我希望完全消除原始指针。
推荐答案
您可以引入其他重载来为您执行延迟:
template <class T>
void f(std::shared_ptr<T> a)
{
f(std::static_pointer_cast<A>(a));
}
template <class T>
void f(std::shared_ptr<const T> a)
{
f(std::static_pointer_cast<const A>(a));
}
您还可以使用std::enable_if
将第一个重载限制为非const
T
,和/或将两个重载限制为派生自A
的T
。
工作原理:
您对某些X
有一个std::shared_ptr<X>
,它既不是A
也不是const A
(它是B
或const B
)。如果没有我的模板重载,编译器必须选择将这个std::shared_ptr<X>
转换为std::shared_ptr<A>
或std::shared_ptr<const A>
。这两种转换都是按等级进行的同样好的转换(都是用户定义的转换),因此存在歧义。
添加模板重载后,有四种参数类型可供选择(让我们分析一下X = const B
案例):
std::shared_ptr<A>
std::shared_ptr<const A>
std::shared_ptr<const B>
从第一个模板实例化,T = const B
。std::shared_ptr<const B>
从第二个模板实例化,T = B
。
const
(在T
之外),因此它更加专门化,因此被选择。
没有规则说"模板更好"。事实上,情况恰恰相反:当模板和非模板的成本相同时,非模板是首选的。这里的诀窍是,模板的成本(不需要转换)低于非模板(需要用户定义的转换)。
这篇关于重载解析和指向常量的共享指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:重载解析和指向常量的共享指针
基础教程推荐
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++,'if' 表达式中的变量声明 2021-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04