2

I want to create a templated class whose variable template arguments are the same as a given std::function. For example

template <typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const> {
    template <template<typename... TArgs> class T>
    using ArgsCopy = T<Args...>;
};

template <typename... Args>
class _forwarder {
public:
    using cb = std::function<void(Args...)>;

    void operator()(Args... args) {
        my_cb(args...);
    }

private:
    cb my_cb;
};

template <typename T>
using Forwarder = function_traits<T>::ArgsCopy<_forwarder>;

I would then use this class as follows

using cb_test = std::function<void(int, float, std::string)>;
Forwarder<cb_test> fwd;
fwd(5, 3.2, "hello");

Visual Studio throws a compilation error: Error C2061: syntax error : identifier 'ArgsCopy'. How do I fix this?

Jordan Crittenden
  • 898
  • 1
  • 9
  • 18

1 Answers1

3

Microsoft's compiler doesn't exactly follow the standard here, and adding template should work:

template <typename T>
using Forwarder = function_traits<T>::template ArgsCopy<_forwarder>;

But if you want your code to be portable, add typename:

template <typename T>
using Forwarder = typename function_traits<T>::template ArgsCopy<_forwarder>;
krzaq
  • 15,660
  • 3
  • 41
  • 59