Template function does not work for pointer-to-member-function taking const ref

Args types cannot be deduced both as const& (from fun parameter declaration) and non-reference from args declaration. A simple fix is to use two separate template type parameter packs:

template<class T, class R, class... Args, class... DeclaredArgs>
R call_or_throw(
    const std::weak_ptr<T>& ptr,
    const std::string& error,
    R (T::*fun)(DeclaredArgs...),
    Args... args);

As a downside, I can imagine slightly longer error messages in case of bad usage.


Note that the template parameter Args's type is deduced as const int& on the 3rd function argument &A::foo, and deduced as int on the 4th function parameter 1. They don't match and cause deduction fails.

You can exclude the 4th parameter from deduction, e.g.

template<class T, class R, class... Args>
R call_or_throw(const std::weak_ptr<T>& ptr, 
                const std::string& error, 
                R (T::*fun)(Args...), 
                std::type_identity_t<Args>... args) {
//              ^^^^^^^^^^^^^^^^^^^^^^^^^^                

LIVE

PS: std::type_identity is supported since C++20; but it's quite easy to implement one.

Tags:

C++

Templates