动态强制转换适用于模板成员函数内的共享指针和弱指针,无需代码重复
Dynamic casting work both shared and weak pointers inside of template member function without code duplication
我有我的 Find 方法,我想同时使用共享指针和弱指针。现场示例
using namespace std;
template<typename value>
struct A
{
template < typename T, typename F >
T Find( F filterFunction)
{
for ( size_t i = 0; i < iteratableList.size(); i++)
{
auto castedTerrain = dynamic_pointer_cast<typename T::element_type>(iteratableList[i]);
if ( castedTerrain && filterFunction(castedTerrain) )
return iteratableList[i];
}
return T();
}
std::vector<value> iteratableList;
};
int main()
{
{
std::vector<std::shared_ptr<std::string>> names = { make_shared<std::string>("needle"), make_shared<std::string>("manyOtherNames") } ;
A<std::shared_ptr<std::string>> iterateable{ names };
iterateable.Find<std::shared_ptr<std::string>>([] ( std::shared_ptr<std::string> in ){ return *in == "needle";});
}
// When I use weak pointer my Find function fails.
//{
// std::vector<std::shared_ptr<std::string>> weakNames ;
// for ( auto elem : names )
// weakNames.push_back(elem)
// A<std::weak_ptr<std::string>> iterateable{ weakNames };
// iterateable.Find<std::weak_ptr<std::string>>([] ( std::weak_ptr<std::string> in ){ return *in == "needle";});
//}
}
我知道我可以做这样的事情 std::is_same< std::weak_ptr ... >
并使用std::true_type
和std::false_type
但我很好奇是否有更好、更干净的方法来避免仅针对.lock()
方法的代码重复。
只需有一个模板函数,您可以使用它来获取"真实"指针。 std::shared_ptr
的专用化只返回参数:
template <typename T>
struct resolve_pointer;
template <typename T>
struct resolve_pointer<std::shared_ptr<T>>
{
static std::shared_ptr<T> resolve(std::shared_ptr<T> & p) const {
return p;
}
};
template <typename T>
struct resolve_pointer<std::weak_ptr<T>>
{
static std::shared_ptr<T> resolve(std::weak_ptr<T> & p) const {
return p.lock();
}
};
现在你的Find
函数代替iteratableList[i]
,使用resolve_pointer<T>::resolve(iteratableList[i])
。
我是一个土豆,一个重载的自由函数也可以工作,并且更容易理解:
template <typename T>
std::shared_ptr<T> resolve_pointer(std::shared_ptr<T> & p) {
return p;
}
template <typename T>
std::shared_ptr<T> resolve_pointer(std::weak_ptr<T> & p) {
return p.lock();
}
如果您的目标是能够扩展代码以提供与具有已实现动态强制转换操作的任何强/弱指针对的互操作性(此处显示 std::strong/weak_ptr 和 boost::strong/weak_ptr(,您可以使用一组特征来执行此操作,例如...当心,前方的龙:
// Defines a resolve static function to get a strong pointer from either
// a strong or a weak pointer.
template <typename T>
struct smart_pointer_info;
template <typename T>
struct smart_pointer_info<std::shared_ptr<T>>
{
typedef std::shared_ptr<T> ptr_type;
typedef T element_type;
typedef std::shared_ptr<T> resolved_type;
static resolved_type resolve(ptr_type & p) {
return p;
}
};
template <typename T>
struct smart_pointer_info<std::weak_ptr<T>>
{
typedef std::weak_ptr<T> ptr_type;
typedef T element_type;
typedef std::shared_ptr<T> resolved_type;
static resolved_type resolve(ptr_type & p) {
return p.lock();
}
};
template <typename T>
struct smart_pointer_info<boost::shared_ptr<T>>
{
typedef boost::shared_ptr<T> ptr_type;
typedef T element_type;
typedef boost::shared_ptr<T> resolved_type;
static resolved_type resolve(ptr_type & p) {
return p;
}
};
template <typename T>
struct smart_pointer_info<boost::weak_ptr<T>>
{
typedef boost::weak_ptr<T> ptr_type;
typedef T element_type;
typedef boost::shared_ptr<T> resolved_type;
static resolved_type resolve(ptr_type & p) {
return p.lock();
}
};
// Provides a static "cast" function that converts a strong pointer T
// into a strong point that points at an object of type D.
template <typename T, typename D>
struct smart_pointer_dynamic_cast;
template <typename T, typename D>
struct smart_pointer_dynamic_cast<std::shared_ptr<T>, D>
{
typedef std::shared_ptr<T> ptr_type;
typedef std::shared_ptr<D> cast_type;
static cast_type cast(ptr_type & p) {
return std::dynamic_pointer_cast<D>(p);
}
};
template <typename T, typename D>
struct smart_pointer_dynamic_cast<boost::shared_ptr<T>, D>
{
typedef boost::shared_ptr<T> ptr_type;
typedef boost::shared_ptr<D> cast_type;
static cast_type cast(ptr_type & p) {
return boost::dynamic_pointer_cast<D>(p);
}
};
// Helper so we can omit the template parameter for the source pointer type.
template <typename D>
struct dynamic_cast_helper
{
template <typename P>
static typename smart_pointer_dynamic_cast<typename smart_pointer_info<P>::resolved_type, D>::cast_type cast(P & p) {
typename smart_pointer_info<P>::resolved_type r = smart_pointer_info<P>::resolve(p);
return smart_pointer_dynamic_cast<typename smart_pointer_info<P>::resolved_type, D>::cast(r);
}
};
// Then we might use it like so:
class A {
public:
virtual void print() {
std::cout << "A::print()" << std::endl;
}
};
class B : public A {
public:
virtual void print() {
std::cout << "B::print()" << std::endl;
}
};
int main()
{
auto x = std::make_shared<B>();
std::weak_ptr<B> xw{x};
auto y = boost::make_shared<B>();
boost::weak_ptr<B> yw{y};
dynamic_cast_helper<A>::cast(x)->print();
dynamic_cast_helper<A>::cast(xw)->print();
dynamic_cast_helper<A>::cast(y)->print();
dynamic_cast_helper<A>::cast(yw)->print();
return 0;
}
(演示(
然后,您的强制转换dynamic_pointer_cast<typename T::element_type>(iteratableList[i])
变得dynamic_cast_helper<typename smart_pointer_info<T>::element_type>::cast(iteratableList[i])
,编译器会推断出沿途的所有类型。
相关文章:
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 如何防止C++遗留代码中的挂起指针
- 理解这行C++指针代码
- 为什么我们不在下面给出的代码中使用指针来实例化C++的实体对象?
- 为什么我的代码在指针方面停止运行?
- 以下与指针相关的代码的输出是什么?
- C++指针问题:如何修复这些代码中的错误?
- 如何使用指针直接从托管代码中的非托管代码中读取矢量数据
- 为什么下面的代码段返回指针指向的值而不是指针的地址?
- 使用指针向量(带代码)C++(以及对其使用的便利性的怀疑)时出现问题
- 为什么从 constexpr 引用生成的程序集代码与从 constexpr 指针生成的程序集代码不同?
- 由于指针算法错误,代码在 memcpy 中崩溃
- 为什么通过定义另一个指针单元格,整个代码停止工作?
- 使用指针编译代码后,.cpp文件将变为随机字符
- OpenCV如何处理Mat作为指针来加速代码
- 我的指针代码 c++ 中的分段错误(核心转储)
- 这两个指针代码有什么区别
- 由于没有明显的原因,请继续在C 的指针代码上遇到错误
- C++:传递和返回指向数组的指针-代码不起作用
- 如何将 Visual Studio 配置为在调试时'skip'智能指针代码?