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中的隐式转换 ...
随机推荐
- 如何在 ubuntu 下使用 Windows 里面的字体
01. 02. 03. 04. 谢谢浏览!
- Web应急:移动端劫持
PC端访问正常,移动端访问出现异常,比如插入弹窗.嵌入式广告和跳转到第三方网站,将干扰用户的正常使用,对用户体验造成极大伤害. 现象描述 部分网站用户反馈,手机打开网站就会跳转到赌博网站. 问题处理 ...
- Notepad++使用护眼便捷小技巧
Notepad++是一款很好用的写笔记和代码的应用. 我们可以用它来写博客草稿和日常的笔记.那么,长时间看一个界面,当然会对眼睛有伤害. 所以,一个护眼的背景.是必须的. 下面就是我经常用到的护眼色, ...
- golang ----array and slice
Go Slices: usage and internals Introduction Go's slice type provides a convenient and efficient mean ...
- WPF DispatcherTimer一些个人看法 (原发布 csdn 2017-04-25 19:12:22)
wpf中的DispatcherTimer基本用法,本文不在叙述.主要写一些不同的,来提醒自己不要再犯同样错误. 前几天写代码时发现.当在非UI线程创建DispatcherTimer实例时,程序无法进入 ...
- pack URI
WPF使用pack URI语法寻找资源. URI负责搜索如下位置的资源: 当前程序集 引用的程序集 相对于程序集的某个位置 应用程序的源站点 pack URI的格式:pack://机构/路径 机构指定 ...
- c# asp.net core取当月第一天和最后一天及删除最后一个字符的多种方法
当月第一天0时0分0秒 DateTime.Now.AddDays( - DateTime.Now.Day).Date 当月最后一天23时59分59秒 DateTime.Now.AddDays( - D ...
- Windows Server - 用tomcat部署finereport
原博地址:https://blog.csdn.net/qq_39019865/article/details/80969728
- 双栈(Dual Stack)
参考博客: 双栈数据结构: https://blog.csdn.net/hebtu666/article/details/83011115 https://blog.csdn.net/cainv89/ ...
- 01. JavaScript基础总结深入
01. 数据类型 1. 分类(2大类) * 基本(值)类型 * Number: 任意数值 * String: 任意文本 * Boolean: true/false * undefined: undef ...