typedef 有效,'using ='不起作用

typedef works, 'using =' doesn't

本文关键字:不起作用 using 有效 typedef      更新时间:2023-10-16

我有一段代码,稍微简化一下,相当于下面的代码,可以正确编译和工作:

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;
}

但是当尝试使用较新的using ... =结构而不是像这样在结构中定义类型时:

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

然后将typename factory_function<Interface, Args...>::type更改为factory_function<Interface, Args...>,我得到一个编译错误:

foo.cc: In function ‘int main(int, char**)’:
foo.cc:31:61: error: no matching function for call to ‘register_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 ...)>’ and ‘std::shared_ptr<Iface> (*)()’
   register_factory<Iface>(1000, create_function<Iface, Impl>);
                                                         ^
foo.cc:31:61: note:   could not resolve address from overloaded function ‘create_function<Iface, Impl>’

更新:这是用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;
}

注释行显示不工作的地方。

对于int register_factory(identifier id, typename factory_function<Interface, Args...>::type factory),编译器无法推断InterfaceArgs类型,因此对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>));

您可以将这两种方法结合使用;)

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;