ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.12k stars 500 forks source link

is_value_semantic_for_function doesn't work as expected #1437

Open niello opened 1 year ago

niello commented 1 year ago

As follows from code, passing by reference or by value is determined as:

    using use_reference_tag =
    meta::all<
        meta::neg<is_value_semantic_for_function<T>>
        ...
    >;

But when we pass some argument to sol::function by value (say type is MyType), in push_reference the T is already MyType&. And if we define MyType as passed by value, we actually get nothing, because for MyType& it is not defined. This causes me to define all these just in case:

template <> struct is_value_semantic_for_function<MyType> : std::true_type {};
template <> struct is_value_semantic_for_function<const MyType> : std::true_type {};
template <> struct is_value_semantic_for_function<MyType&> : std::true_type {};
template <> struct is_value_semantic_for_function<const MyType&> : std::true_type {};

And there is the second issue. While we may want to pass [const] MyType and const MyType& by value, we may at the same time want explicit MyType& to be passed by reference. It is typical pattern for C++ signatures. But we can't define that because MyType& specialization is used for MyType args.

The perfect behaviour would be to define specialization for MyType only and to have MyType& as an automatic exception from the rule, bound always by reference. And if someone wants a reference to be passed by value, let them explicitly use const MyType& on C++ side.