今天看书,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[] = { , , , , -, -, };
const size_t SIZE = sizeof a / sizeof a[]; gt_n<int> predicate();
cout << "gt_n.getVal() = " << predicate.getVal() << endl; cout << count_if(a, a + SIZE, not1(predicate)) << endl; //
return ;
} ///:~

编译时报错

: 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属性的,因此这个地方是书的作者写错了。

ERROR C3848:具有类型"const XXX" 的表达式会丢失一些 const-volatile 限定符以调用"YYY" with"ZZZ"的更多相关文章

  1. ISO/IEC 9899:2011 条款6.7.3——类型限定符

    6.7.3 类型限定符 语法 1.type-qualifier: const restrict volatile _Atomic 约束 2.除了指针类型(其被引用的类型是一个对象类型)之外的类型,不应 ...

  2. C语言中类型限定符

    通常用类型和存储类别来描述一个变量. C90还增加了两个属性:恒常性(constancy).易变性(volatility): 分别用关键字const和volatile来声明. 这两个关键字创建的类型是 ...

  3. C 类型限定符

    C 类型限定符 1. Introduction C 语言中的大部分类型都可以用称为限定符(qualifier)的关键字 const. volatile. restrict. _Atomic 加以限定. ...

  4. 类型限定符volatile

    目录 类型限定符volatile 强制内存读取 禁止编译优化 注意:volatile不能够保证线程同步 volatile bool flag; volatile int a; 添加volatile限定 ...

  5. C#调用Excel报 error CS1969: 找不到编译动态表达式所需的一个或多个类型。是否缺少引用?

    转自[http://blog.csdn.net/bodybo/article/details/43191319] 程序需要读取Exel文件,有如下代码段 object oMissing = Syste ...

  6. c语言的类型、运算符与表达式

    title: 2017-10-17c语言的类型.运算符与表达式 tags: c程序设计语言 grammar_cjkRuby: true --- 1.1 数据类型 char 字符型,一个字节 int 整 ...

  7. 变量和基本类型——复合类型,const限定符,处理类型

    一.复合类型 复合类型是指基于其他类型定义的类型.C++语言有几种复合类型,包括引用和指针. 1.引用 引用并非对象,它只是为一个已存在的对象所起的另外一个名字. 除了以下2种情况,其他所有引用的类型 ...

  8. const限定符、constexpr和常量表达式------c++ primer

    编译器将在编译过程中把用到const变量的地方都替换成对应的值,为了执行这种替换,编译器必须知道变量的初始值.如果程序包含多个文件,则那个用了const对象的文件都必须能访问到它的初始值才行.要做到这 ...

  9. 2变量与基本类型之const限定符

    一.const介绍: const对象一旦被创建其值就不能再改变,所以const对象必须初始化.任何试图对const赋值的行为都会引发错误. 二.初始化和const: 对const对象的主要限制就是只能 ...

随机推荐

  1. [Todo]对于thrift和protobuf比较好的描述

    比较跨语言通讯框架:thrift和Protobuf 全部thrift protobuf 前两天想在微博上发表一个观点:在现在的技术体系中,能用于描述通讯协议的方式很多,xml,json,protobu ...

  2. Microsoft Office Word 2007 文档结构图突然变小的解决办法

    前记: 一个word文档不知道修改了什么,突然发现文档结构图显示的文字变得非常的小了. 用ctrl+鼠标滚轮只能放大或是缩小行间距,对文字没有什么变化. 解决办法: 1.打开文档结构图 点击视图,勾选 ...

  3. idea maven 报-source 1.5 中不支持 diamond 运算符

    需要修改 project setting 中的

  4. linux查看当前shell的方法

    这篇文章主要对比一下 source 命令执行shell文件和 ./ping.sh 这种方式执行shell文件的区别. 1. source   ping.sh 这个是在当前的shell 中执行 ping ...

  5. 用rpm安装软件的常用步骤

    假设软件叫software.rpm 1.安装前,查看是否安装过用 rpm -q software 2.安装时,用 rpm -ivh software.rpm 3.安装后想删除,用 rpm -e sof ...

  6. k-means聚类学习

    4.1.摘要 在前面的文章中,介绍了三种常见的分类算法.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别与之对应.但是很多时候上述条件得不到满足,尤其是在 ...

  7. java中循环控制结构

    1. break结束break所在循环 for(i……) { for(j……) { break;  //结束循环j } } 2.带标签的break. java中的标签只用在循环语句前面. outer: ...

  8. Learning English From Android Source Code:1

    英语在软件行业的重要作用不言自明,尤其是做国际项目和写国际软件,好的英语表达是项目顺利进行的必要条件.纵观眼下的IT行业.可以流利的与国外客户英文口语交流的程序猿占比并非非常高.要想去国际接轨,语言这 ...

  9. Openerp workflow 工作流批注模块

    转自:http://blog.csdn.net/yeahliu/article/details/17207289 2013-12-22 添加workflow_stop标识,感谢广州-jerry 201 ...

  10. hdu 4742 Pinball Game 3D(三维LIS&amp;cdq分治&amp;BIT维护最值)

    Pinball Game 3D Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...