- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试将派生类作为 std::shared_pointer 传递给一个函数,该函数的参数是具有模板的基类。
这是一个完整的例子:
template <class T>
class Base {
public:
std::string typeName()
{
int status;
char *realName = abi::__cxa_demangle(typeid(T).name(), 0, 0, &status);
std::string ret(realName);
free(realName);
return ret;
}
};
class Derived : public Base<float> {};
我想调用的函数是带有共享指针的“doSomething”。
template <class V>
void doSomethingNotShared(Base<V> *test)
{
std::cout << "Not shared type: " << test->typeName() << std::endl;
};
template <class V>
void doSomething(std::shared_ptr<Base<V>> test)
{
std::cout << "Shared type: " << test->typeName() << std::endl;
};
这里是 main 函数,展示了我想如何使用它并指出编译错误。
int main()
{
std::shared_ptr<Derived> testval1 = std::shared_ptr<Derived> (new Derived());
doSomething(testval1); // <- Compilation error
Derived *testval2 = new Derived();
doSomethingNotShared(testval2);
std::shared_ptr<Base<float>> testCast = std::dynamic_pointer_cast<Base<float>>(testval1); // Would rather not have to do this if there is another way ...
doSomething(testCast); // <- No error runs fine
}
有什么方法可以使 doSomething(testval1);
有效吗? ?我希望不必使用 dynamic_pointer_cast
(或任何其他类型的类型转换机制)并仅使用 Derived。
主要错误是:std::shared_ptr<Derived> is not derived from std::shared_ptr<Base<V> >
我可以创建一个“AnyBase”类来删除模板参数,但这样会删除我在实际应用程序中设置的一些类型安全,这是必须的。
我正在考虑的一件事是在新类 AnyBase
之间创建一个映射和 std::shared_ptr<AnyBase>
, 然后使用函数 doSomethingNotShared
用于处理类型安全,并使用查找映射来获取 shared_ptr。 (见下文)
std::map<AnyBase *, std::shared_ptr<AnyBase>>
编辑:
从我的应用程序中检查类型安全的示例:
template <class V, class W, class X>
void addRuleEdge(Bookkeeper<V> *bookkeeper, std::shared_ptr<IRule<V, W>> rule, ITask<W, X> *consumer)
在这种情况下,我想在 Bookkeeper
之间匹配类型对于 V
在第一个模板类型中 IRule
和 IRule
的第二个模板参数的匹配类型( W
) 第一个模板类型为 ITask
.这用作用户的 API 调用,以确保在添加边缘时类型在编译时正确排列。
最佳答案
一个简单的解决方案是更改 doSomething
以处理更广泛的参数集。
template <class V>
void doSomething(std::shared_ptr<V> test)
{
std::cout << "Shared type: " << test->typeName() << std::endl;
};
编辑:使用您的最新示例,我编写了一个示例,说明您如何通过更广泛的重载和 std::enable_if
或 static_assert
实现您想要的。我提供了空类以允许示例编译。
#include <memory>
template<class V>
class Bookkeeper {};
template<class V, class W>
class IRule {};
// Some rule class derived from IRule compatible with Bookkeepr
class RealRule : public IRule<int, float> {};
template<class W, class X>
class ITask {};
// Some task class derived from ITask, compatible with RealRule
class RealTask : public ITask<float, double> {};
// Some task class derived from ITask, not compatible with RealRule
class BadTask : public ITask<int, double> {};
template <class V, class Rule, class W, class X>
typename std::enable_if<std::is_base_of<IRule<V, W>, Rule>::value, void>::type
addRuleEdge(Bookkeeper<V> *bookkeeper, std::shared_ptr<Rule> rule, ITask<W, X> *consumer)
{
// Do work
}
int main()
{
Bookkeeper<int> my_book_keeper;
auto my_rule = std::make_shared<RealRule>();
RealTask my_task;
// Compiles
addRuleEdge(&my_book_keeper, my_rule, &my_task);
BadTask bad_task;
// Won't compile (no matching overload)
addRuleEdge(&my_book_keeper, my_rule, &bad_task);
}
如果您只是想在使用错误类型时收到通知,您也可以选择使用 static_assert
。
template <class V, class Rule, class W, class X>
void addRuleEdge(Bookkeeper<V> *bookkeeper, std::shared_ptr<Rule> rule, ITask<W, X> *consumer)
{
static_assert(std::is_base_of<IRule<V, W>, Rule>::value, "Type mismatch!");
// Do work
}
int main()
{
Bookkeeper<int> my_book_keeper;
auto my_rule = std::make_shared<RealRule>();
RealTask my_task;
// Compiles
addRuleEdge(&my_book_keeper, my_rule, &my_task);
BadTask bad_task;
// Won't compile (error "Type mismatch!")
addRuleEdge(&my_book_keeper, my_rule, &bad_task);
}
关于带有模板基类的 C++ std::shared_pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42565239/
因此,我正在尝试加深对 shared_ptr 的理解,如果多个共享 ptr 指向同一资源共享指针,则可以处理在销毁指向资源的最后一个指针之前不应调用 destrcutor 的情况。 这是我的示例代码:
有一段代码: A.cpp class MySomeClass: public SomeClass { public: void specificMethod(); } class A {
我有一个基本多态类(带有虚方法)和一个派生类。我正在尝试使用以下代码 boost::shared_ptr ptr( new derived_class() ); 但是编译器返回如下错误
我有一个派生自 std::enable_shared_from_this 的类。所有类对象都由共享指针管理,因此当没有更多共享指针指向它们时,它们会自动销毁。 我有一个类方法,它从程序的数据结构中删除
我有一个由 Node 和 Edge 类表示的有向图模型。每个 Node 对象都包含指向其所有传出和传入边的指针,每个 Edge 对象都包含指向其起点和终点(Node 对象)的指针。 class Mod
我正在尝试将派生类作为 std::shared_pointer 传递给一个函数,该函数的参数是具有模板的基类。 这是一个完整的例子: template class Base { public:
我使用 reset() 作为我的 shared_pointer 的默认值(相当于 NULL)。 但是如何检查 shared_pointer 是否为 NULL? 这会返回正确的值吗? boost::sh
我正在使用一个程序,其中我的代码调用第三方库,该库使用 boost 和 shared_pointers 来创建一个大而复杂的结构。这个结构是在我调用的方法中创建的,在方法结束时我知道程序已经完成。 对
我有一个函数返回类型为 const A 的共享指针。 std::shared_ptr getPointer() const; 我有一个函数需要 A 类型的 shared_ptr。 void foo(s
我正在尝试使用 tr1 的 shared_ptr 和 Qt 4.8.2 但我遇到了一些麻烦。这是我的代码: #include "mainwindow.h" #include "ui_mainwindo
我一直在尝试从 map 中填充 vector 。我知道如何以更传统的方式做到这一点,但我试图用 STL 算法(一个衬里)来实现它作为某种训练:)。 原始 map 类型是: std::map > 目标
我有以下问题,我想知道是否有更好的方法来解决它: class myObj { public: typedef std::shared_ptr handle; typedef std::
我基本上是这样设置的: class B { /* ... */}; class C1 : public B { /* ... */}; class C2 : public B { /* ... */}
我是一名优秀的程序员,十分优秀!