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中的隐式转换 ...
随机推荐
- CMake的含义和用法解读
什么是 CMake 你或许听过好几种 Make 工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等.这些 Make 工 ...
- Java 函数式编程--流操作
GitHub Page: http://blog.cloudli.top/posts/Java-函数式编程-流操作/ 外部迭代到内部迭代 在使用集合类时,通用的方式是在使用 for 循环集合上进行迭代 ...
- C#中 char、byte、string
var str = "我是中国人";var str1 = "abc"; char[] chars = str.ToCharArray();char[] char ...
- javascript 函数表达和闭包
函数表达式和闭包 针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内.写这个主要是当个笔记加总结 存在的问题请大家多多指正! 定义函数的两种方法 函数声明: function functi ...
- Android中实现Activity的透明背景效果
实现方式一(使用系统透明样式) 通过配置 Activity 的样式来实现,在 AndroidManifest.xml 找到要实现透明效果的 Activity,在 Activity 的配置中添加如下的代 ...
- iOS批量添加SDK自动打包GUI工具
背景 1.之前在给游戏开发商做SDK接入技术支持的时候,很多cp对iOS开发技术并不是很了解,对接SDK和打包都很迷糊,虽然我们根据他们的开发环境输出了不同的插件解决方案,这一步已经把接入SDK的复杂 ...
- <Android Studio> 4.Adapter的那些事 <一>
android 的表格显示和Windows桌面开发原理不同,其他平台转过来的同学要有心理准备,不要拿桌面开发的思维模式来思考android上的各种表格. 一.原理 此处使用ArrayAdapter来记 ...
- nginx的 ngx.var ngx.ctx ngx.req
ngx.var 是获取 Nginx 的变量,需要经历字符串 hash.hash 表查找等过程. ngx.ctx 仅仅是一个 Lua table 而已,它的引用存放在 ngx_lua 的模块上下文(ct ...
- linux 利用 crontab 实现 程序开机启动/crontab任务的多种实现方法
方法一,用户登录服务器,直接修改: crontab -e 然后添加: @reboot [nohup] {命令} ctrl + O ctrl + x 方法二,指定用户进行修改: sudo crontab ...
- 终极 Shell——ZSH
https://zhuanlan.zhihu.com/p/19556676 在开始今天的 MacTalk 之前,先问两个问题吧: 1.相对于其他系统,Mac 的主要优势是什么?2.你们平时用哪种 Sh ...