为 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;
有没有办法在使用 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;