今天看书,Thinking in c++ volume 2 "Adaptable function objects"
里面作者说:
Suppose, for example, that we want to make the function object gt_n, defined
earlier in this chapter, adaptable. All we need to do is the following:class gt_n : public unary_function<int, bool> {
int value;
public:
gt_n(int val) : value(val) {}
bool operator()(int n) {
return n > value;
}
};
然后我做了一个template
#ifndef GREATERTHANN_HPP #define GREATERTHANN_HPP #include <functional> namespace ZJ { template <class ArgType, class Result = bool> struct gt_n : public std::unary_function<ArgType, Result> { private: ArgType value; public: gt_n(const ArgType& val) : value(val) {} Result operator()(ArgType n) { return (n > value); } ArgType getVal() { return value; } }; } #endif // GREATERTHANN_HPP
测试代码:
//: C06:GreaterThanN.cpp #include "GreaterThanN.hpp" #include <iostream> #include <functional> #include <algorithm> using namespace ZJ; using namespace std; int main() { int a[] = { 10, 1, 2, 30, -10, -9, 3 }; const size_t SIZE = sizeof a / sizeof a[0]; gt_n<int> predicate(2); cout << "gt_n.getVal() = " << predicate.getVal() << endl; cout << count_if(a, a + SIZE, not1(predicate)) << endl; // 3 return 0; } ///:~
编译时报错
: error C3848: 具有类型“const ZJ::gt_n<int,bool>”的表达式会丢失一些 const-vola
tile 限定符以调用“bool ZJ::gt_n<int,bool>::operator ()(ArgType)”
with
[
ArgType=int
]
看起来大概意思是:你用的gt_n<int, bool>的instance具有const属性,但是调用该instance的表达式(也就是“bool ZJ::gt_n<int,bool>::operator ()(ArgType))不具有const属性,丢失const,所以无法通过编译
最开始我在看main里面,predicate不具有const属性啊
后来去查std::not1的文档:http://en.cppreference.com/w/cpp/utility/functional/not1
template< class Predicate > std::unary_negate<Predicate> not1(const Predicate& pred);
因为std::not1用的是const Predicate&,所以我的predicate到not1之中以后就是const Predicate&了,所以在调用operator()的时候要求operator()也具有const属性,否则就会导致丢失const限定符的错误
因此解决办法就是给operator()加上const属性,如下:
#ifndef GREATERTHANN_HPP #define GREATERTHANN_HPP #include <functional> namespace ZJ { template <class ArgType, class Result = bool> struct gt_n : public std::unary_function<ArgType, Result> { private: ArgType value; public: gt_n(const ArgType& val) : value(val) {} Result operator()(ArgType n) const { return (n > value); } ArgType getVal() { return value; } }; } #endif // GREATERTHANN_HPP
好了,现在可以通过编译了。
你可以从上面std::not1文档的Example代码看出,operator()是加了const属性的,因此这个地方是书的作者写错了。