我编写了一个模板化的Matrix
结构,它通过使用地图在内部抽象连续索引。
Matrix<TCell, TKey> m;
有一个扩展结构的功能,我想让用户能够传递一个填充新创建的单元格的函数指针(initFunc
)。
void ExpandMatrix( Matrix<TCell, TKey>* matrix,
std::set<TKey>* keys_c,
std::set<TKey>* keys_r,
??? /*Function pointer to callback function */
)
现在我的问题是,这个用户提供的函数需要传递一个指针和单元格的键,而不是我使用的任何内部计数器。并且这些通过模板定义为TCell
和TKey
。所以我不能使用它,因为还不知道究竟TCell
或TKey
是什么:
typedef void (*initFunc)(TCell* pCell, TKey key_c, TKey key_r)
就我的研究而言,无法模拟函数指针:
template<typename TCell, typename TKey>
typedef void (*initFunc)(TCell* pCell, TKey key_c, TKey key_r)
我目前所做的是将函数包装在用户被认为派生的类中,但这对用户来说很麻烦。难道没有更好的解决方案吗?
template <typename TCell, typename TKey>
class DefaultCellInitializer
{
public:
virtual void Initialize(TCell* t, TKey key_c, TKey key_r)
{
return;
}
};
template<typename TCell, typename TKey>
void ExpandMatrix( Matrix<TCell, TKey>* matrix,
std::set<TKey>* keys_c,
std::set<TKey>* keys_r,
CellInitializer<TCell, TKey> initializer = DefaultCellInitializer)
注意:我需要允许一个默认值,它无法应对该方法的传统用法。 C ++ 11是受欢迎的,但它必须在MSVC 2012上编译。由于政治原因,Boost不是一个选项。
答案 0 :(得分:3)
您不需要typedef
模板函数指针。您可以直接将ExpandMatrix()
的参数类型定义为函数指针:
template<typename TCell, typename TKey>
void ExpandMatrix(Matrix<TCell, TKey>* matrix,
void (*initFunc)(TCell*, TKey, TKey) = defaultCellInitializer) {}
和defaultCellInitializer()
可能是
template<typename TCell, typename TKey>
void defaultCellInitializer(TCell* pCell, TKey key_c, TKey key_r) {
... ...
}
答案 1 :(得分:2)
您可以使用std::function
使用这些模板类型。这可以绑定到lambda。
template <typename TCell, typename TKey>
void ExpandMatrix( Matrix<TCell, TKey>* matrix,
std::set<TKey>* keys_c,
std::set<TKey>* keys_r,
std::function<void(TCell*, TKey, TKey)> callback
);
然后是lambda:
ExpandMatrix(/* args */, []( /* type list for arguments */ ) {
/* implementation */
});
将lambda绑定到std::function
时,您需要在所需参数列表中提供类型。
如果您不限于lambda,也可以使用函数指针。
此外,std::function
可以用自己的模板参数替换,并以与标准库在其算法中使用谓词等相同的方式使用(例如std::find_if
);
template <typename TCell, typename TKey, typename Callback>
void ExpandMatrix( Matrix<TCell, TKey>* matrix,
std::set<TKey>* keys_c,
std::set<TKey>* keys_r,
Callback callback
);
同样,callback
可以绑定到函数指针,仿函数,lambda等。