out_value/pure_out_value policy compiles with gcc, but fails with msvc

"Tristan" <[email protected]>
Newsgroups gmane.comp.lang.lua.bind.user
Message-ID <[email protected]>
Hi,

I have the following code, which does not compile with msvc 9.0 
SP1. But
with gcc version 4.4.1 (TDM-2 mingw32) it compiles and works.

#include <lua.hpp>

#include <iostream>
#include <string>
#include <luabind/luabind.hpp>
#include <luabind/out_value_policy.hpp>

struct error_code
{
    int value;
    std::string message;
};

std::string greet(bool a, error_code& ec)
{
    if(a)
    {
        ec.value = 42;
        ec.message = "Ops!";
    }
    else
    {
        ec.value = 0;
        ec.message = "OK";
    }
    return "abc123";
}

extern "C"  __declspec(dllexport)
int luaopen_lbteset(lua_State* L)
{
    using namespace luabind;

    open(L);

    module(L)
    [
        def("greet", &greet, pure_out_value(_2))
    ];

    return 0;
}

With msvc 9.0 it produces the following error messages:
1>Compiling...
1>pure_out_value_policy.cpp
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2784: 'luabind::detail::char_array<sizeof(identity<T>::type)> 
luabind::detail::indirect_sizeof_test(luabind::detail::by_value<T>)
' : could not deduce template argument for 
'luabind::detail::by_value<T>' from 
'luabind::detail::by_reference<T>'
1>        with
1>        [
1>            T=error_code
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(71) 
: see declaration of 'luabind::detail::indirect_sizeof_test'
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(238) 
: see reference to class template instantiation 
'luabind::detail::indirect_sizeof<T>' being compiled
1>        with
1>        [
1>            T=a1 
1>        ]
1>        
d:\code\boost\boost_trunk\boost\mpl\aux_\preprocessed\plain\apply_wr
ap.hpp(49) : see reference to class template instantiation 
'luabind::detail::pure_out_value_policy<BOOST_PP_ITERATION_0,Policie
s>::apply<T,Direction>' being compiled
1>        with
1>        [
1>            BOOST_PP_ITERATION_0=2,
1>            Policies=luabind::detail::null_type,
1>            T=a1 ,
1>            Direction=luabind::detail::lua_to_cpp
1>        ]
1>        
d:\code\boost\boost_trunk\boost\preprocessor\iteration\detail\local.
hpp(37) : see reference to class template instantiation 
'boost::mpl::apply_wrap2<F,T1,T2>' being compiled
1>        with
1>        [
1>            F=p1,
1>            T1=a1,
1>            T2=luabind::detail::lua_to_cpp
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\detail\call.hpp(89) : see 
reference to function template instantiation 'int 
luabind::detail::invoke_normal<std::string(__cdecl 
*)(bool,error_code 
&),boost::mpl::vector3<T0,T1,T2>,Policies>(lua_State *,const 
luabind::detail::function_object &,luabind::detail::invoke_context 
&,const F &,Signature,const Policies 
&,boost::mpl::long_<N>,boost::mpl::false_)' being compiled
1>        with
1>        [
1>            T0=std::string,
1>            T1=bool,
1>            T2=error_code &,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>,
1>            F=std::string (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>,
1>            N=2
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\detail\call.hpp(101) : 
see reference to function template instantiation 'int 
luabind::detail::invoke0<std::string(__cdecl *)(bool,error_code 
&),boost::mpl::vector3<T0,T1,T2>,Policies,boost::is_void<T>>(lua_Sta
te *,const luabind::detail::function_object 
&,luabind::detail::invoke_context &,const F &,Signature,const 
Policies &,IsVoid,boost::mpl::false_)' being compiled
1>        with
1>        [
1>            T0=std::string,
1>            T1=bool,
1>            T2=error_code &,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>,
1>            
T=std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,
1>            F=std::string (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>,
1>            
IsVoid=boost::is_void<std::basic_string<char,std::char_traits<char>,
std::allocator<char>>>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\make_function.hpp(40) : 
see reference to function template instantiation 'int 
luabind::detail::invoke<std::string(__cdecl *)(bool,error_code 
&),boost::mpl::vector3<T0,T1,T2>,Policies>(lua_State *,const 
luabind::detail::function_object &,luabind::detail::invoke_context 
&,const F &,Signature,const Policies &)' being compiled
1>        with
1>        [
1>            T0=std::string,
1>            T1=bool,
1>            T2=error_code &,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>,
1>            F=std::string (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\make_function.hpp(39) : 
while compiling class template member function 'int 
luabind::detail::function_object_impl<F,Signature,Policies>::call(lu
a_State *,luabind::detail::invoke_context &) const'
1>        with
1>        [
1>            
F=std::basic_string<char,std::char_traits<char>,std::allocator<char>
> (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\make_function.hpp(98) : 
see reference to class template instantiation 
'luabind::detail::function_object_impl<F,Signature,Policies>' being 
compiled
1>        with
1>        [
1>            
F=std::basic_string<char,std::char_traits<char>,std::allocator<char>
> (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\function.hpp(28) : see 
reference to function template instantiation 'luabind::adl::object 
luabind::make_function<std::string(__cdecl *)(bool,error_code 
&),boost::mpl::vector3<T0,T1,T2>,Policies>(lua_State 
*,F,Signature,Policies)' being compiled
1>        with
1>        [
1>            T0=std::string,
1>            T1=bool,
1>            T2=error_code &,
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>,
1>            F=std::string (__cdecl *)(bool,error_code &),
1>            
Signature=boost::mpl::vector3<std::string,bool,error_code &>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\function.hpp(27) : while 
compiling class template member function 'void 
luabind::detail::function_registration<F,Policies>::register_(lua_St
ate *) const'
1>        with
1>        [
1>            
F=std::basic_string<char,std::char_traits<char>,std::allocator<char>
> (__cdecl *)(bool,error_code &),
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\function.hpp(50) : see 
reference to class template instantiation 
'luabind::detail::function_registration<F,Policies>' being compiled
1>        with
1>        [
1>            
F=std::basic_string<char,std::char_traits<char>,std::allocator<char>
> (__cdecl *)(bool,error_code &),
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>
1>        ]
1>        d:\code\luabind\pure_out_value_policy.cpp(121) : see 
reference to function template instantiation 'luabind::scope 
luabind::def<std::string(__cdecl *)(bool,error_code 
&),luabind::detail::policy_cons<H,T>>(const char *,F,const Policies 
&)' being compiled
1>        with
1>        [
1>            
H=luabind::detail::pure_out_value_policy<2,luabind::detail::null_typ
e>,
1>            T=luabind::detail::null_type,
1>            F=std::string (__cdecl *)(bool,error_code &),
1>            
Policies=luabind::detail::policy_cons<luabind::detail::pure_out_valu
e_policy<2,luabind::detail::null_type>,luabind::detail::null_type>
1>        ]
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2784: 'luabind::detail::char_array<sizeof(identity<T>::type)> 
luabind::detail::indirect_sizeof_test(luabind::detail::by_const_poin
ter<T>)' : could not deduce template argument for 
'luabind::detail::by_const_pointer<T>' from 
'luabind::detail::by_reference<T>'
1>        with
1>        [
1>            T=error_code
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(68) 
: see declaration of 'luabind::detail::indirect_sizeof_test'
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2784: 'luabind::detail::char_array<sizeof(identity<T>::type)> 
luabind::detail::indirect_sizeof_test(luabind::detail::by_pointer<T>
)' : could not deduce template argument for 
'luabind::detail::by_pointer<T>' from 
'luabind::detail::by_reference<T>'
1>        with
1>        [
1>            T=error_code
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(65) 
: see declaration of 'luabind::detail::indirect_sizeof_test'
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2784: 'luabind::detail::char_array<sizeof(identity<T>::type)> 
luabind::detail::indirect_sizeof_test(luabind::detail::by_const_refe
rence<T>)' : could not deduce template argument for 
'luabind::detail::by_const_reference<T>' from 
'luabind::detail::by_reference<T>'
1>        with
1>        [
1>            T=error_code
1>        ]
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(62) 
: see declaration of 'luabind::detail::indirect_sizeof_test'
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2893: Failed to specialize function template 
'luabind::detail::char_array<sizeof(identity<T>::type)> 
luabind::detail::indirect_sizeof_test(luabind::detail::by_reference<
T>)'
1>        With the following template arguments:
1>        'error_code'
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(78) : error 
C2866: 'luabind::detail::indirect_sizeof<T>::value' : a const 
static data member of a managed type must be initialized at the 
point of declaration
1>        with
1>        [
1>            T=a1 
1>        ]
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(238) : error 
C2975: 'Size' : invalid template argument for 
'luabind::detail::pure_out_value_converter', expected compile-time 
constant expression
1>        d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(168) 
: see declaration of 'Size'
1>d:\code\luabind-0.9-rc1\luabind\out_value_policy.hpp(221) : 
warning C4200: nonstandard extension used : zero-sized array in 
struct/union
1>        Cannot generate copy-ctor or copy-assignment operator 
when UDT contains a zero-sized array
1>        
d:\code\boost\boost_trunk\boost\preprocessor\iteration\detail\local.
hpp(37) : see reference to class template instantiation 
'luabind::detail::pure_out_value_converter<Size,Policies>' being 
compiled
1>        with
1>        [
1>            Size=0,
1>            Policies=luabind::detail::null_type
1>        ]

Of course non primitive types do not require this, but I prefer to 
have
the error_code also as a real return value.  Is there as way to fix
this?

I think [1] had the same problem.

Is there another way to bind functions which return multiple values 
with
luabind?

I use ...
Lua 5.1
luabind 0.9-rc1
Boost from trunk rev. 58556

[1] 
http://sourceforge.net/mailarchive/forum.php?thread_name=eha6ii%24n1
2%245%40sea.gmane.org&forum_name=luabind-user
-- 
Tristan


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.