【问题标题】:Lambda with variadic template带有可变参数模板的 Lambda
【发布时间】:2015-05-12 05:51:54
【问题描述】:

遇到的问题,只在gcc编译里面听说过。我一直在 Visual Studio 2013(更新 3)中编程。

我需要在某个正确的线程中创建一些对象。 此外,还需要能够传递它们创建的函数。

这段代码

class Object1;
class Object2;

class MyClass
{
    public:

        std::function<Object1*( const std::vector<int>& )> creatorForObject1() const;
        std::function<Object2*( int, double )> creatorForObject2() const;

    private:

        // exec 'handler' in other thread when there is a possibility
        void execInRightThread( std::function<void()> handler ) const;

        // need be called in right thread
        Object1& craeteObject1( const std::vector<int>& param );
        Object2& craeteObject2( int param1, double param2 );

        template<class TObject, class ...TParams>
        std::function<TObject*( TParams... )> creatorForObject( TObject&( MyClass::*creator )( TParams... ) ) const;
};


template<class TObject, class ...TParams>
std::function<TObject*( TParams... )> MyClass::creatorForObject( TObject&( MyClass::*creator )( TParams... ) ) const
{
    return [ this, &creator ]( TParams... params )
    {
        TObject* result = nullptr;
        MyClass& me = *const_cast<MyClass*>( this );
        me.execInRightThread( [ &me, &result, &creator, &params... ]()
        {
            result = &( me.*creator )( params... );
        } );
        while( result == nullptr );  // ugliness
        return result;
    };
}

std::function<Object1*( const std::vector<int>& )> MyClass::creatorForObject1() const
{
    return creatorForObject( &MyClass::craeteObject1 );
}

std::function<Object2*( int, double )> MyClass::creatorForObject2() const
{
    return creatorForObject( &MyClass::craeteObject2 );
}

报告错误

error C3521: 'params' is not a parameter pack
error C3546: '...' : there are no parameter packs available to expand
error C2065: 'params' : undeclared identifier

排队

me.execInRightThread( [ &me, &result, &creator, &params... ]()

请帮忙。

提前致谢。

【问题讨论】:

  • 我无法使用 GCC 4.9.2 重现此内容。您使用的是什么编译器版本?也许你应该升级。
  • 在 4.9 及以上版本下无法重现。
  • 我使用 Microsoft Visual C++ 2013
  • 我的意思是我已经阅读过关于没有新版本 gcc 编译器的类似问题。

标签: c++11 lambda variadic-templates


【解决方案1】:

你可以试试:

template<class TObject, class ...TParams>
std::function<TObject*( TParams... )> MyClass::creatorForObject( TObject&( MyClass::*creator )( TParams... ) ) const
{
    return [ this, &creator ]( TParams... params )
    {
        TObject* result = nullptr;
        MyClass& me = *const_cast<MyClass*>( this );
        me.execInRightThread( [ & ]()
        {
            result = &( me.*creator )( params... );
        } );
        while( result == nullptr );  // ugliness
        return result;
    };
}

也许你应该按价值捕获......

【讨论】:

  • 很遗憾,效果一样。
  • 另外,我犯了一个错误。而有me.execInRightThread( [ &amp;me, &amp;result, &amp;creator, &amp;params... ]()需要me.execInRightThread( [ &amp;me, &amp;result, creator, &amp;params... ]()
【解决方案2】:

如果内部 lambda 创建一个单独的函数,这可以工作,但我不明白为什么上面写的不起作用。

class MyClass
{
   ...

    private:

        template<class TObject, class ...TParams>
        std::function<TObject*( TParams... )> creatorForObject( TObject&( MyClass::*creator )( TParams... ) ) const;

        template<class TObject, class ...TParams>
        TObject* temporaryCreator( TObject&( MyClass::*creator )( TParams... ), TParams... params );
};


template<class TObject, class ...TParams>
std::function<TObject*( TParams... )> MyClass::temporaryCreator( TObject&( MyClass::*creator )( TParams... ), TParams... params )
{
    TObject* result = nullptr;
    execInRightThread( [ this, &result, creator, &params... ]()
    {
        result = &( me.*creator )( params... );
    } );
    while( result == nullptr );  // ugliness
    return result;
}

template<class TObject, class ...TParams>
std::function<TObject*( TParams... )> MyClass::creatorForObject( TObject&( MyClass::*creator )( TParams... ) ) const
{
    MyClass& me = *const_cast<MyClass*>( this );
    return [ &me, creator ]( TParams... params )
    {
        return temporaryFunction<TObject, TParams...>( creator, params... );
    };
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多