mac*_*inn 4 c++ templates function-object
我有一个类应该根据用户提供的谓词过滤其内容。我给出的接口规定引用谓词:
\n\nclass Test {\n vector<int> data;\npublic:\n template <class PREDTYPE>\n void filter(PREDTYPE& pred) {\n return;\n }\n};\nRun Code Online (Sandbox Code Playgroud)\n\n我还得到了一段测试代码,大致如下:
\n\nclass Filter {\npublic:\n bool operator()(int) const {\n return false;\n }\n};\n\nint main() {\n Test test;\n test.filter(Filter());\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这不会\xe2\x80\x99t 编译,说cannot bind non-const lvalue reference of type 'Filter&' to an rvalue of type 'Filter'。如果我将测试代码更改为
int main() {\n Test test;\n Filter filter;\n test.filter(filter);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n它有效,但这取决于最终用户,我无法控制他们的行为。我尝试重载过滤器方法,创建一个版本,该版本将按值接受谓词,然后通过引用传递它,但这也不会\xe2\x80\x99t编译,并显示消息call of overloaded 'filter(Filter&)' is ambiguous。
因此我的问题是:是否可以构造一个同时接受谓词的右值和左值的过滤器?
\n简而言之,是的(C++11)
您只需依靠参考折叠规则来确保这一点:
template <typename PREDTYPE>
void filter(PREDTYPE&& pred) { // notice the &&
// ... Whatever
// Use perfect forwarding *IF* you can
std::forward<PREDTYPE>(pred)(some_stuff);
// Do not use pred after it has been forwarded!
}
Run Code Online (Sandbox Code Playgroud)
这将接受右值和左值,而不必依赖const- 引用(因此您的谓词仍然可以是可变的)。如果您坚持使用较旧的 C++ 标准,最好的办法是使用 const 引用(上面突出显示了警告)或将过滤器嵌入到 an 中std::function并依赖于调用站点的隐式转换。