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中的隐式转换 ...
随机推荐
- 算法设计与分析(李春保)练习题答案v2
----------------------------------------------------- Page 1 --------------------------------------- ...
- 【mybatis】标签条件中判断入参属性值是否包含子字符串
可以直接使用 contains判断 <foreach collection="list" item="item" index="index&qu ...
- 在eclipse中,用maven创建一个web项目工程
1.在eclipse中用maven创建项目,右键new>>Maven Project 2.点击next继续 3.点击next继续,选择maven-archetype-webapp, 4.点 ...
- 使用VMware 15 安装虚拟机和使用CentOS 8
前言: 最近在学习Linux和.Net Core,学习一些跨平台的知识.首先我用的虚拟机软件是VMware-15.1.0,Linux系统是CentOS-8-x86_64-1905-dvd1. 一.安装 ...
- 2019-11-29-C#-字典-Dictionary-的-TryGetValue-与先判断-ContainsKey-然后-Get-的性能对比
原文:2019-11-29-C#-字典-Dictionary-的-TryGetValue-与先判断-ContainsKey-然后-Get-的性能对比 title author date CreateT ...
- 基于.net EF6 MVC5+WEB Api 的Web系统框架总结(4)-Excel文件读、写操作
Excel文件读.写可以使用Office自带的库(Microsoft.Office.Interop.Excel),前提是本机须安装office才能运行,且不同的office版本之间可能会有兼容问题.还 ...
- python2.7写的图形密码生成器
#coding:utf8import random,wxdef password(event): a = [chr(i) for i in range(97,123)] b = [chr(i) for ...
- 修改Nginx配置参数解决http状态码:413上传文件大小限制问题
修改Nginx上传文件大小限制 我们使用ngnix做web server的时候,nginx对上传文件的大小有限制,默认是1M. 当超过大小的时候会报413(too large)错误.这个时候我们要修改 ...
- 用JSON.stringify去实现深拷贝的弊端
无法处理function啦还有RegExp啦,还有无法处理循环引用对象(这个我还没有test) 就前两点的话 var a={ a:, b:new RegExp('test'), c:function( ...
- php封装协议的两道题
这几天终于刷完了自己说是要刷完的那几道题,赶紧写几篇博客记录.. 1. 先看看这个网站:https://blog.csdn.net/qq_41289254/article/details/81388 ...