Typedef works, 'using =' is not

I have a piece of code that, a simplified bit, boils down to the following, which compiles and works correctly.

template <typename Interface, typename... Args>
struct factory_function {
  typedef function<shared_ptr<Interface> (Args...)> type;
};

template <typename Interface, typename Implementer, typename... Args>
shared_ptr<Interface> create_function(Args... args) {
  return make_shared<Implementer>(args...);
}

template <typename Interface, typename... Args>
  int register_factory(identifier id, typename factory_function<Interface, Args...>::type factory) {
}

int main(int argc, char *argv[]) {
  register_factory<Iface>(1000, create_function<Iface, Impl>);
  return 0;
}

But when trying to use a new construct using ... =instead of a typedef in a structure like this:

template <typename Interface, typename... Args>
using factory_function = function<shared_ptr<Interface> (Args...)>;

and then change typename factory_function<Interface, Args...>::typeto factory_function<Interface, Args...>, I get a compilation error:

foo.cc: In functionint main(int, char**)’:
foo.cc:31:61: error: no matching function for call toregister_factory(int, <unresolved overloaded function type>)’
   register_factory<Iface>(1000, create_function<Iface, Impl>);
                                                         ^
foo.cc:31:61: note: candidate is:
foo.cc:17:5: note: template<class Interface, class ... Args> int register_factory(identifier, factory_function<Interface, Args ...>)
 int register_factory(identifier id, factory_function<Interface, Args...> factory) {
     ^
foo.cc:17:5: note:   template argument deduction/substitution failed:
foo.cc:31:61: note:   mismatched types ‘std::function<std::shared_ptr<Iface>(Args ...)>’ andstd::shared_ptr<Iface> (*)()’
   register_factory<Iface>(1000, create_function<Iface, Impl>);
                                                         ^
foo.cc:31:61: note:   could not resolve address from overloaded functioncreate_function<Iface, Impl>’

UPDATE: This is a complete, compiled test case compiled with g++ -std=c++11 foo.cc:

#include <functional>
#include <memory>

using namespace std;

typedef int identifier;

template <typename Interface, typename... Args>
struct factory_function {
  typedef function<shared_ptr<Interface> (Args...)> type;
};
//template <typename Interface, typename... Args>
//using factory_function = function<shared_ptr<Interface> (Args...)>;

template <typename Interface, typename Implementer, typename... Args>
shared_ptr<Interface> create_function(Args... args) {
  return make_shared<Implementer>(args...);
}

template <typename Interface, typename... Args>
int register_factory(identifier id, typename factory_function<Interface, Args...>::type factory) {
//int register_factory(identifier id, factory_function<Interface, Args...> factory) {
}

class Iface {
public:
  virtual void foo() = 0;
};

class Impl : public Iface {
public:
  virtual void foo() {}
};

int main(int argc, char *argv[]) {
  register_factory<Iface>(1000, create_function<Iface, Impl>);
  return 0;
}

Commented lines indicate that does not work.

+4
source share
2 answers

You can make it work by combining the two approaches :)

template <typename Interface, typename... Args>
struct fa_fu_helper {
  typedef function<shared_ptr<Interface> (Args...)> type;
};

template <typename Interface, typename... Args>
using factory_function = typename fa_fu_helper<Interface, Args...>::type;
+2
source

int register_factory(identifier id, typename factory_function<Interface, Args...>::type factory) Interface Args, register_factory<Iface>(1000, create_function<Iface, Impl>); int register_factory(identifier id, typename factory_function<Interface>::type);

( ) int register_factory(identifier id, factory_function<Interface, Args...> Args (Interface Iface), , , (std::shared_ptr<Iface> (*)() function<std::shared_ptr<Iface>(Args...)>)

- create_function<Iface, Impl> std::function. :

template <typename R, typename...Args>
std::function<R(Args...)> make_function(R (*f)(Args...))
{
    return f;
}

:

register_factory<Iface>(1000, make_function(create_function<Iface, Impl>));
+6

Source: https://habr.com/ru/post/1541925/


All Articles