传递boost :: function,它将模板参数作为参数默认为NULL

时间:2014-08-15 12:40:16

标签: c++ templates boost functor

我正在尝试制作这样的函数:

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);

甚至没有必要重载任何东西:),谢谢。

1 个答案:

答案 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);