mercredi 29 août 2018

Perfect forwarding of C++ overloaded and templated functors and its arguments

Suppose we have a function that looks like:

template <typename F, typename... A>
inline void execute(F&& functor, A&& ... args) {
    std::forward<decltype(functor)>(functor)(std::forward<decltype(args)>(args)...);
}

This works for simple non-templated functions. However, I am trying to perfect-forward a templated function(a quite contrived one):

namespace detail {

template <typename CodecImpl>
class codec
{
public:
    //
    // Encoding

    // Convenient version, returns an std::string.
    static std::string encode(const uint8_t* binary, size_t binary_size);
    static std::string encode(const char* binary, size_t binary_size);
    ...
};

class base64_rfc4648
{
public:
    template <typename Codec> using codec_impl = stream_codec<Codec, base64_rfc4648>;

    static CPPCODEC_ALWAYS_INLINE constexpr size_t alphabet_size() {
        static_assert(sizeof(base64_rfc4648_alphabet) == 64, "base64 alphabet must have 64 values");
        return sizeof(base64_rfc4648_alphabet);
    }
    static CPPCODEC_ALWAYS_INLINE constexpr char symbol(alphabet_index_t idx)
    {
        return base64_rfc4648_alphabet[idx];
    }
    ...
};

} // namespace detail

using base64_rfc4648 = detail::codec<detail::base64<detail::base64_rfc4648>>;

Trying to forward the above:

std::string buf("hello world");
execute(base64_rfc4648::encode, buf.c_str(), buf.size());

Does not work. Template deduction fails:

note: couldn't deduce template parameter 'F'

and it also notes:

No matching function for call to 'execute(<unresolved overloaded function type>, const char*, std::__cxx11::basic_string<char>::size_type)'

How can I fix this?

NOTE: I kept the information short above for readability, but if more info is needed I can add.

Aucun commentaire:

Enregistrer un commentaire