我正在尝试制作这样的函数:
template<typename T, typename Val>
void someFun(vector<T>& container, int a, int b, int c, boost::function<bool(T&)> selector = NULL)
{
Val* ptrToElement = someGetElementFunction(container[i]);
if (selector && selector(*ptrToElement))
{
cout << "do something!" << endl;
}
}
这样选择器是可选的,可以传递或不传递,用法应如下所示:
someFun(1,2,3);
boost::function<int(someClass&)> someSelector = boost::bind(...)
someFun(1,2,3, someSelector);
但是由于T类型是通用的,它似乎无法完成,无论如何都可以绕过它,或者可能有更好的解决方案来解决这个问题?
编辑: 很抱歉,似乎我没有给出足够的细节,该函数实际上是一个元素选择器,整个示例现在已经编辑,应该看起来更清晰。
所以直到现在它已经通过总是传递一些函数来处理,即使没有选择器并且所有元素都应该由函数处理,它通过传递来处理:
boost::function<bool(someObject&)> selectAllObjects = boost::lambda::constant(true);
someFun(someObjContainer, 1, 2, 3, selectAllObjects);
但这个解决方案看起来很糟糕,每当要选择所有对象时,你必须制作那个愚蠢的selectAll选择器并进一步传递它。我试图通过传递可选函数来消除它,并仅在指针不为NULL时处理选择元素。
重载的问题是很多重复的代码,假设someFun包含20行代码,重载它只是为了添加该功能会使其加倍。
编辑2: 我找到了解决方案,如果有人会有类似的问题,那么解释:
谢谢你们的帮助,对不起一开始就没有说清楚,这可能会给我节省很多时间:(但无论如何 - 问题有点复杂,容器没有&#39;仅仅是一个值容器,而是一个字典的键容器,可以从中获取值,因此类型T实际上是键的类型。编译器无法推断出Val类型,因为它根本不是&#39 ; t在调用函数时显式传递(现在看来很明显......)。
以下显然有效:
someFun<int, myClass>(someVector, 1, 2, 3);
someFun<int, myClass>(someVector, 1, 2, 3, someSelector);
甚至没有必要重载任何东西:),谢谢。
答案 0 :(得分:1)
当您致电someFun(1, 2, 3)
时,编译器并不知道您所使用的功能模板的哪种专业化,因为它无法推断出T
应该是什么类型。它无法在不知道function<void(T&)>
的情况下创建T
类型的默认参数。
在C ++ 11中,如果您可以使用合理的默认值,则可以为T
添加默认模板参数:
template<typename T = int>
void someFun(int a, int b, int c, boost::function<int(T&)> funPtr = nullptr)
{
}
但是这个功能的设计并没有多大意义......如果你不知道它是什么类型的话,你希望对function
对象做什么?
有两个重载函数可能更有意义:
void someFun(int a, int b, int c);
template<typename T>
void someFun(int a, int b, int c, boost::function<int(T&)> funPtr);