c++隐式转换(implicit conversion)
1.缘由
最近在使用nlohmann的json,发现有些地方不是特别好用,所以就想自己修改一下(目的是为了增加类似jsoncpp中可以//增加注释的功能),在看源码的时候看到了一个迷惑的地方,就是解析json
JSON_HEDLEY_WARN_UNUSED_RESULT
static basic_json parse(detail::input_adapter&& i,
const parser_callback_t cb = nullptr,
const bool allow_exceptions = true)
{
basic_json result;
parser(i, cb, allow_exceptions).parse(true, result);
return result;
}
第一个参数我传入的是一个istream,但是这里接收的是一个类。
调试的时候发现,先创建了一个input_adapater类
class input_adapter
{
public:
// native support
JSON_HEDLEY_NON_NULL()
input_adapter(std::FILE* file)
: ia(std::make_shared<file_input_adapter>(file)) {}
/// input adapter for input stream
input_adapter(std::istream& i)
: ia(std::make_shared<input_stream_adapter>(i)) {} /// input adapter for input stream
input_adapter(std::istream&& i)
: ia(std::make_shared<input_stream_adapter>(i)) {} input_adapter(const std::wstring& ws)
: ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {} input_adapter(const std::u16string& ws)
: ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {} input_adapter(const std::u32string& ws)
: ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {} /// input adapter for buffer
template<typename CharT,
typename std::enable_if<
std::is_pointer<CharT>::value and
std::is_integral<typename std::remove_pointer<CharT>::type>::value and
sizeof(typename std::remove_pointer<CharT>::type) == ,
int>::type = >
input_adapter(CharT b, std::size_t l)
: ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
在这里找到了istream,一个构造函数。
当时比较懵,还有这种使用方法?用c++这么久没有发现哪里有明确指出这种使用方法。潜意思中觉着可能是隐式转换。
自己写了几个测试程序发现,确实是这样,类如果有一个对应类型的构造函数,是可以默认转换的。
后来查资料,突然想起来,经常用的string不就是这样用吗?
string str = "test";
我们最常用的一种方法,这里就是调用了string里面const char*为参数的构造函数。可以调试查看xstring里面的这个函数
basic_string(_In_z_ const _Elem * const _Ptr)
: _Mybase()
{ // construct from [_Ptr, <null>)
_Tidy_init();
assign(_Ptr);
}
2.c++类的类型转换(转换构造函数 Converting constructor)
参考 https://en.cppreference.com/w/cpp/language/converting_constructor https://zh.cppreference.com/w/cpp/language/converting_constructor
一个类的构造函数,如果没有声明explicit,并且传入的确定参数只有一个(这里的意思就是,不一定这个构造函数就一个参数,可以多个参数,但是其他参数都是有默认值的),那么这个就是转换构造函数。
作用就是把一个类型隐式的转换成类。
3.explicit
参考 https://zh.cppreference.com/w/cpp/language/explicit
与隐式转换对应出现的就是explicit关键字,既然提供了隐式转换,那么肯定也有禁止隐式转换的方法。explicit关键字就是声明在构造函数前,明确指定,不允许隐式转换构造,必须是明确的
4.user-defined conversion
参考 https://en.cppreference.com/w/cpp/language/cast_operator
实际上上面的隐式转换属于这个范畴,就是用户自定义的转换。允许隐式和显式的转换类与一个其他类型。
使用方法,就是operator加上要转换的类型,加上函数的括号,不能加参数,函数内部返回这个值。
operator conversion-type-id
operator 类型 ()
{
return 类型;
}
class C1
{
public:
operator int()
{
return ;
}
}; int i1 = C1;
mysql connector中的sqlstring
class SQLString
{
std::string realStr; ~SQLString() {} SQLString() {} operator const std::string &() const
{
return realStr;
}
}
SQLString a = "aaa";
string b = a;
就是在上面这种赋值的时候,会调用到这个函数,帮忙转换成另外一种类型,最好前后加const,防止改变内容
c++隐式转换(implicit conversion)的更多相关文章
- 显示转换explicit和隐式转换implicit
用户自定义的显示转换和隐式转换 显式转换implicit关键字告诉编译器,在源代码中不必做显示的转型就可以产生调用转换操作符方法的代码. 隐式转换implicit关键字告诉编译器只有当源代码中指定了显 ...
- Scala之隐式转换implicit详解
假设我们有一个表示文本的行数的类LineNumber: class LineNumber ( val num : Int ) 我们可以用这个类来表示一本书中每一页的行数: val lineNumOfP ...
- C++ - 模板类模板成员函数(member function template)隐式处理(implicit)变化
模板类模板成员函数(member function template)隐式处理(implicit)变化 本文地址: http://blog.csdn.net/caroline_wendy/articl ...
- Scala中的Implicit(隐式转换,隐式参数,隐式类)
文章来自:http://www.cnblogs.com/hark0623/p/4196452.html 转发请注明 代码如下: /** * 隐式转换 隐式参数 隐式类 */ //隐式转换 class ...
- Scala隐式转换和隐式参数
隐式转换 Scala提供的隐式转换和隐式参数功能,是非常有特色的功能.是Java等编程语言所没有的功能.它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法.通过这些功能, ...
- Scala基础:闭包、柯里化、隐式转换和隐式参数
闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数. val i: Int = 20 //函数func的方法体中使用了在func外部定义的变量 那func就 ...
- 【Scala】什么是隐式转换?它又能用来干嘛?该怎么用
文章目录 定义 隐式参数 隐式转换 隐式值:给方法提供参数 隐式视图 将Int和Double类型转换为String 狗狗学技能(使用别的类中的方法) 使用规则 定义 隐式参数 隐式参数指在函数或者方法 ...
- C# 转换符的重载 显示、隐式转换
class Complex { //保存转换的值 Int32 v; public Complex(Int32 x) { v = x; } public Int32 ToInt32() { return ...
- Scala 隐式转换及应用
什么是隐式转换 我们经常引入第三方库,但当我们想要扩展新功能的时候通常是很不方便的,因为我们不能直接修改其代码.scala提供了隐式转换机制和隐式参数帮我们解决诸如这样的问题. Scala中的隐式转换 ...
随机推荐
- 解决SpringBoot无法读取js/css静态资源的新方法
前言 作为依赖使用的SpringBoot工程很容易出现自身静态资源被主工程忽略的情况.但是作为依赖而存在的Controller方法却不会失效,我们知道,Spring MVC对于静态资源的处理也不外乎是 ...
- MongoDB 学习笔记 ---创建用户
MongoDB安装好了之后,开始学习常用命令 首先,运行MongoDB, 记住,先不用带参数--auth /usr/local/mongodb/bin/mongod -dbpath=/usr/loca ...
- DNS:从零搭建公司内网DNS服务器
写在前面的话 网上关于 DNS 的文章其实一搜索一大把,但是看别人的文档一般都会有个问题,乱,不讲究,全是 ctrl c + ctrl v,我个人是看不下去的.头皮发麻.所以决定自己来写写这方面的东西 ...
- [转] JavaScript数组去重(12种方法)
数组去重,一般都是在面试的时候才会碰到,一般是要求手写数组去重方法的代码.如果是被提问到,数组去重的方法有哪些?你能答出其中的10种,面试官很有可能对你刮目相看.在真实的项目中碰到的数组去重,一般都是 ...
- spring好文章整理
彻底搞明白Spring中的自动装配和Autowired IDEA编译spring 5源码 Spring源码——IDEA读Spring源码环境搭建 导入spring源码org.springframewo ...
- PHP之面向对象(下)
1,类的创建 class 2,对象的创建 new关键字 3,成员的添加 修饰符 添加成员需要三个修饰符 public 公开的 定义公共的属性和方法,类的外部,内部,子类都可以使用 protected ...
- #pragma once和#ifndef
C语言中的头文件只是简单的复制粘贴. C语言中变量.函数.结构体的定义和声明两个过程是分离的.声明通常放在头文件中,为了防止重复声明,需要保证头文件中的内容在构建obj文件时只被包含一次.这可以通过# ...
- ASP.NET Core使用Quartz定时调度
在应用程序开发过程中,经常会需要定时任务调度功能,本篇博客介绍Asp.net Core如何使用Quartz完成定时调度 一.Quartz使用步骤 创建调度器scheduler,并开启 创建Job作业 ...
- Qt Creator清除最近工程历史信息
Qt Creator清除最近工程历史信息 随着不断打开和关闭qt工程,欢迎->Projects->Recent projects下的历史工程信息越来越多,是该清理一下了,强迫症会追求干净一 ...
- QQ空间自动点赞js脚本
这是很久前写的脚本了,在浏览器打开QQ空间,并在控制台输入代码就可 时间间隔最好开大点,不然容易被暂时冻结账号 function autoLike() { var list=document.getE ...