【问题标题】:A workaround with templates for changing a type使用模板更改类型的解决方法
【发布时间】:2013-08-11 12:30:16
【问题描述】:

考虑这个委托类:

template <class DELEGATECLASS, class METHODPTRSPEC>
class CLDelegate
{
public:
    CLDelegate();
    CLDelegate( DELEGATECLASS* instancePtr, METHODPTRSPEC methodPtr );
    CLDelegate( const CLDelegate& rhs );

    DELEGATECLASS* pInstance_;
    METHODPTRSPEC pMethod_;
};

//-----------------------------------------------------------------------------
//
template <class DELEGATECLASS, class METHODPTRSPEC>
CLDelegate<DELEGATECLASS, METHODPTRSPEC>::CLDelegate()
    : pInstance_( nullptr )
    , pMethod_( nullptr )
{}

//-----------------------------------------------------------------------------
//
template <class DELEGATECLASS, class METHODPTRSPEC>
CLDelegate<DELEGATECLASS, METHODPTRSPEC>::CLDelegate( DELEGATECLASS*
        instancePtr, METHODPTRSPEC methodPtr )
    : pInstance_( instancePtr )
    , pMethod_( methodPtr )
{}

//-----------------------------------------------------------------------------
//
template <class DELEGATECLASS, class METHODPTRSPEC>
CLDelegate<DELEGATECLASS, METHODPTRSPEC>::CLDelegate( const CLDelegate& rhs )
    : pInstance_( rhs.pInstance_ )
    , pMethod_( rhs.pMethod_ )
{}

我想在另一个类中使用这个委托,但我必须为整个类提供模板参数,这是我不想要的,像这样:

template<class DELEGATECLASS, class METHODPTR>
class SomeClass
{
public:
    IOVFUCam();
    ~IOVFUCam();

    // Data Members
private:
    ...
    const CLDelegate<DELEGATECLASS, METHODPTR>& del_;
};

由于我不想在整个类上使用模板参数,我想知道我的类中是否可以有一个虚拟委托并更改其类型(在编译时?):

struct EmptyType
{};

class SomeClass
{
public:
    template<class DELEGATECLASS, class METHODPTR>
    IOVFUCam( CLDelegate<DELEGATECLASS, METHODPTR> del )
     : del_(del)
    {};

    ~IOVFUCam();

    // Data Members
private:
    ...
    const CLDelegate<EmptyType, EmptyType>& del_;
};


FrameHandler handler;
CLDelegate<FrameHandler,
           void(FrameHandler::*)( IOBuffer::Ptr )>
           del( &handler, &FrameHandler::ProcessImage );
SomeClass obj( del );

我很快读到了 Alexandrescu 写的关于 TypeTraits 的文章,我想知道这是否可以应用于我的问题或其他技术?

非常感谢!

【问题讨论】:

  • 可能你没有告诉你CLDelegate的一些细节,但为什么不只使用std::bind(和SomeClass中的一个nuary std::function&lt;void()&gt;容器)
  • bind中使用的方法必须是静态的吧?
  • s/必须/可能/。这不是强制性的。 bind可以绑定所有可调用实体
  • 好的,你能告诉我/解释一下如何在我的代码中使用它吗?

标签: c++ templates compile-time typetraits


【解决方案1】:

你见过 std::allocator 吗?它有一个“重新绑定”类型,允许 std::allocator 在编译时给你一个 std::allocator。

template <class DELEGATECLASS, class METHODPTRSPEC>
class CLDelegate
{
public:
    template<class D, class M>
    struct rebind {
        typedef CLDelegate<D, M> type;
    };

    CLDelegate();
    CLDelegate( DELEGATECLASS* instancePtr, METHODPTRSPEC methodPtr );
    CLDelegate( const CLDelegate& rhs );

    DELEGATECLASS* pInstance_;
    METHODPTRSPEC pMethod_;
};

这样,如果您已经有 CLDelegate 类型,则可以使用以下代码获取不同的 CLDelegate 类型。

typename MyDelType::rebind<NewDel, NewSpec>::type

这就是你要找的吗?

【讨论】:

  • 如果您能告诉我们更多关于您正在尝试做什么的信息,我们或许能够引导您走上更好的道路。我现在相当不确定手头的问题,我不确定你是否正确地解决了这个问题。
  • 对不起,我对这个小技巧太兴奋了,忘了正确解释我的问题。我解决了所有问题,除了剩下的一件小事。我目前正在编写一个要点来向您展示代码。
  • Here 是要点。我的问题是成员del_ 不是动态对象。所以构造函数中的del_实际上是一个本地对象。所以我要么必须将rebind 代码放入初始化列表,要么将del_ 设为动态对象...您的意见是什么?
  • Arf,我认为这没有帮助,因为我意识到禁止将 typename EmptyDel::rebind 分配给 EmptyDel * :(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多