1

次のテンプレート関数があります...

template< class T > T *create_object( lua_State *L )    
{
    // Get a raw block of memory, managed by Lua.
    void *mem = lua_newuserdata( L, sizeof( T ) );
    // Construct the object in the allocated memory.
    T *object = new (mem) T;
    // Do other stuff here...
    return object;
}

... Lua スクリプト言語で使用する C++ オブジェクトを割り当てて設定します。オブジェクトのコンストラクターに引数を渡せるように、この関数を拡張したいと思います。次のようになります。

template< class T > T *create_object( lua_State *L, ??? ctor_args )    
{
    void *mem = lua_newuserdata( L, sizeof( T ) );
    T *object = new (mem) T( ctor_args ); // Call correct constructor as determined by args.
    // ...
    return object;
}

...そして、次のように動作します:

class widget
{
    public:
        // Multiple constructors
        widget(); // #1
        widget( const widget &w ); // #2
        widget( int width, int height, float x, float y ); //#3
};

class font
{
    public:
        font( std::vector<uint8_t> );
}

// Other classes with multiple constructors.

// Example usage: (L = lua_State pointer)
create_object<widget>( L ); // Pass no arguments - use constructor #1
create_object<widget>( L, existing_widget ); // Pass one argument- use constructor #2
create_object<widget>( L, 128, 64, 100.0f, 100.0f ); // Pass 4 arguments - use construct #3
create_object<font>( L, buffer ); // Just to show it needs to work with many object types...
... and so on ...

次のようになる可変個引数テンプレートを回避します。

create_object<widget, int, int, float, float >( L, 256, 512, 120.0f, 0.0f );

いいだろう。

これは c++11 で可能ですか?

更新: 現在、-pedantic をオンにして gcc 4.6 を使用しています。非コンパイラ固有のソリューションが優先されます。

4

1 に答える 1

9

このように、可変個引数テンプレートを適切にサポートしている場合は、次のようになります。

template< class T, typename... Args > 
T *create_object( lua_State *L, Args&&... args)    
{
    void *mem = lua_newuserdata( L, sizeof( T ) );
    T *object = new (mem) T(std::forward<Args>(args)...);
    // ...
    return object;
}

これにより、参照が正しく転送されます。コンストラクターでさえ、引数の一部を(constまたはnot)参照で取得し、その他は値で取得します。

于 2012-03-29T09:01:09.443 に答える