为 typedef 的函数指针推导模板参数

deduce template argument for typedef'd function pointer

有没有办法在使用 typedef 时推导出函数指针的模板参数?我的示例代码是:

struct A {};
void func(const A&) {};

template <typename T>
struct FuncPtr
{
    typedef void(*Type)(const T&);
};

void f_(FuncPtr<A>::Type) {}

template <typename T> // I'd like to hide the messy function pointer in a typedef
void f1(typename FuncPtr<T>::Type fp) { f_(fp); }

template <typename T> // this works, but "fp" is really several lines long
void f2(void(*fp)(const T&)) { f_(fp); }

有了这个,我可以打电话给 f2(AFunc)。但我宁愿有更接近 f1(func) 的东西,因为在我的实际代码中,函数指针的声明要长得多。我需要有一个实际的函数指针,而不是仅仅传递一个模板参数,这样我就可以调用 f_().

不适用于您当前的设置。 ::* 左边的所有内容都是非推导上下文,因为元函数可以对类型应用任意图灵完备转换,并且在任何情况下都没有保证原始类型和结果之间的一对一映射。所以语言甚至没有尝试。

但是别名模板可以工作:

template <class T>
using FuncPtr = void (*)(const T&);

template <typename T>
void f3(FuncPtr<T> fp) { return f_(fp); }

*正式称为“nested-name-specifier 使用 qualified-id" ([temp.deduct.type]/p5).

As “Effective Modern C++” Item 9,Prefer alias declarations to typedefs 说:

In particular, alias declarations may be templatized (in which case they’re called alias templates), while typedefs cannot. This gives C++11 programmers a straightforward mechanism for expressing things that in C++98 had to be hacked together with typedefs nested inside templatized structs.For example, consider defining a synonym for a linked list that uses a custom allocator, MyAlloc. With an alias template, it’s a piece of cake:

template<typename T
using MyAllocList = std::list<T, MyAlloc<T>>;
MyAllocList<Widget> lw; 

With a typedef, you pretty much have to create the cake from scratch:

template<typename T> 
struct MyAllocList { 
 typedef std::list<T, MyAlloc<T>> type; 
}; 
MyAllocList<Widget>::type lw;