有没有办法在使用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_()
。
答案 0 :(得分:4)
不适合您当前的设置。 ::
* 左侧的所有内容都是非推导的上下文,因为元函数可以对类型应用任意的图灵完全转换,并且无论如何都不能保证一对一 - 原始类型和结果之间的一个映射。所以语言甚至没有尝试。
但是别名模板可以使用:
template <class T>
using FuncPtr = void (*)(const T&);
template <typename T>
void f3(FuncPtr<T> fp) { return f_(fp); }
* 正式名称为使用 qualified-id 指定的类型的“嵌套名称说明符” ([temp.deduct.type] / P5)。子>
答案 1 :(得分:1)
作为“有效的现代C ++”第9项,首选别名声明为typedefs说:
特别是,别名声明可能会被模板化(在这种情况下) 它们被称为别名模板),而typedef则不能。这给了 C ++ 11程序员是表达事物的直接机制 在C ++ 98中,必须与嵌套在其中的typedef一起被黑客攻击 模板化结构。例如,考虑为使用自定义分配器MyAlloc的链表定义同义词。使用别名模板,它是小菜一碟:
template<typename T
using MyAllocList = std::list<T, MyAlloc<T>>;
MyAllocList<Widget> lw;
使用typedef,你几乎必须创建蛋糕 划痕:
template<typename T>
struct MyAllocList {
typedef std::list<T, MyAlloc<T>> type;
};
MyAllocList<Widget>::type lw;