由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 问个C++的operator conversation function问题
相关主题
请教问题VB, C++初学者清推荐书籍
一个 default constructor 的问题哪位大侠有如下书籍的电子版,或者下载地址,多谢
C++ 中 myobject * a =new myobject[n] 的问题C++0x
[合集] 一些C++问题读Bjarne Stroustrup写得The C++ programming language 是不是经常有不知所谓的感觉。
Is the order of initialization a, b, c or c, b, a?(zz)C++11新特性
The untold truth about C++这么好的帖子没人转?
How to initialize object in constructor?有必要开个c++版
C++,大家觉得最值得买最想买最不后悔买的书是哪本?Bjarne Stroustrup C++第四版电子版出来了
相关话题的讨论汇总
话题: c++话题: operator话题: init话题: explicit
进入Programming版参与讨论
1 (共1页)
r*g
发帖数: 186
1
struct S{
S(int){}
};
struct SS{
int m;
SS(int x): m(x){}
explicit operator S(){return S(m);}
};
void f(S s){}
int main()
{
SS ss(1); // ok; 默认构造函数
S s1 = ss; // 错误; 拷贝构造函数不能使用显式转换
S s2(ss); // ok; 直接构造函数可以使用显式转换 ???
// 为什么? 这里难道不是 S s2(static_cast(ss))吗???
// 而且我的理解这里是先ss转成S型的临时变量
// 然后调用copy constructor
// 为什么说这里是直接构造函数?
f(ss); // 错误; 从SS向S的转换必须是显式的.
// 译注: 强制类型转换也可使用显式转换,例如
// S s3 = static_cast(ss);
return 0;
}
原文出处:
https://www.chenlq.net/books/cpp11-faq/cpp11-faq-chinese-version-series-expl
icit-conversion-operator.html
参考文献有一有意思的东西:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2333.h
里面有一段说:
Modify 12.3.2 class.conv.fct paragraph 2 as indicated:
A conversion function may be explicit (7.1.2 dcl.fct.spec), in which case it
is only considered as a user-defined conversion where the direct- initiali
zation syntax (8.5 dcl.init) or where casts (5.2.9 expr.static.cast, 5.4 ex
pr.cast) are used. Otherwise, user-defined User-defined conversions are not
restricted to use in assignments and initializations.
[ Example:
class Y { };
struct Z {
explicit operator Y() const;
// ...
};
void h(Z z) {
Y y1(z); // ok: direct-initialization 这里也是对的, 为啥啊?
// 为什么不是Y y1(static_cast(z)); ?
Y y2 = z; // ill-formed: copy-initialization 这个我能理解
// 应该改成y2 = static_cast(z);
Y y3 = (Y)z; // ok: cast notation
}
void g(X a, X b)
{
int i = (a) ? 1+a : 0;
int j = (a&&b) ? a+b : i;
if (a) { // ...
}
}
-- end example ]
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
~
【 】 Ctrl-Q 求救 状态 [插入][2,1][ ][ ] 时间【Sun Jun 7 16:27】※ 来源:·BBS 未名空间站 网址:mitbbs.com 移动:在应用商店搜索未名空间·[FROM: 173.]
A*******e
发帖数: 2419
2
以下两个是不一样的。前者叫direct initialization,后者叫copy initialization。
copy init不能用显示转换,就像你注释里解释的那样。
S s(ss);
S s = ss;
另外f(ss)也是copy init
Copy-initialization is less permissive than direct-initialization: explicit
constructors are not converting constructors and are not considered for copy
-initialization.
http://en.cppreference.com/w/cpp/language/copy_initialization

【在 r*g 的大作中提到】
: struct S{
: S(int){}
: };
: struct SS{
: int m;
: SS(int x): m(x){}
: explicit operator S(){return S(m);}
: };
: void f(S s){}
: int main()

r*g
发帖数: 186
3
to AlphaCode 你看看我理解的对不对
感觉我这种半路出家的半吊子学C++坑太多了
以前认为C很多坑
现在觉得C++不仅继承了C的坑, 还挖了很多新的坑
我发现我C++的很多基本概念还没弄明白
常年把C++当C在用

// 所以不会有任何问题
// 首先: 根据链接:
http://en.cppreference.com/w/cpp/language/explicit
解释:
explicit operator type ( ) (since C++11)
specifies that this user-defined conversion function is only considered f
or direct initialization (including explicit conversions)
所以explicit operator S(){return S(m);}这个用户自定义转换函数只能用于direct
init,但是这里S s1 = ss; 不是direct init而是copy init:
我臆测为什么不是direct init:
因为direct init需要一个对应的S::S(SS)构造函数, 但是在S的定义中这个东西没有,
编译器能够默认生成的是一个S::S(const S&), 如果没有那个explicit, 而是直接:
operator S(){ return S(m);}
那么这个user defined conversion function返回的临时变量S(m)刚好可以匹配S::S(
const S&)这个编译器提供的默认版本, 于是就能通过编译.
但是由于加了这个explicit, 这个东西根本不能用于copy init, 所以报错通不过编译
这就是为什么原文中有个注释:
// 错误; 拷贝构造函数不能使用显示转换
这个注释是Bjarne Stroustrup写的然后翻译
所以如果无法理解注释肯定是我错 :)
//继续下面这行代码 S s2(ss)
//这个时候是直接构造了, 因为存在函数S::S(int)并且explict operator S()可以用
于直接构造, 所以顺利通过
// 错误的原因是f接受的是f(S), 由于explicit operator S()只能用于direct init和
强制类型转换, 所以不行.
我臆测不行是因为实参向形参传递参数实际是一个copy init的过程
所以这个就基本和上面分析的错误原因一样的
// 标准中明确说明了支持, 所以正确
expl
it
initiali
ex
not

【在 r*g 的大作中提到】
: struct S{
: S(int){}
: };
: struct SS{
: int m;
: SS(int x): m(x){}
: explicit operator S(){return S(m);}
: };
: void f(S s){}
: int main()

r*g
发帖数: 186
4
标准中说引入explicit是为了抑制意料之外的隐士类型转换
这个东西来自于C, 在C++中继承了这一特性
但是就挖出了这么多坑
最开始explict Constructor(other)
是为了抑制其他other2 先转换为other再调用
Constructor(other)
引入operator other()的目的是有时候other类是使用者无法修改的
比如是一些闭源的代码
这时候other2类中加入operator other()的自定义转换函数就能使得
从other可以转换到other2 other2也能转换到other
作为一种"对称". (我参考的原帖下面reference中解释)
但是引入了这个东西后
就使得影视类型转化变得更加复杂
于是又引入了explicit operator other()的概念
........

【在 r*g 的大作中提到】
: to AlphaCode 你看看我理解的对不对
: 感觉我这种半路出家的半吊子学C++坑太多了
: 以前认为C很多坑
: 现在觉得C++不仅继承了C的坑, 还挖了很多新的坑
: 我发现我C++的很多基本概念还没弄明白
: 常年把C++当C在用
:
: // 所以不会有任何问题
: // 首先: 根据链接:
: http://en.cppreference.com/w/cpp/language/explicit

A*******e
发帖数: 2419
5
正确

【在 r*g 的大作中提到】
: to AlphaCode 你看看我理解的对不对
: 感觉我这种半路出家的半吊子学C++坑太多了
: 以前认为C很多坑
: 现在觉得C++不仅继承了C的坑, 还挖了很多新的坑
: 我发现我C++的很多基本概念还没弄明白
: 常年把C++当C在用
:
: // 所以不会有任何问题
: // 首先: 根据链接:
: http://en.cppreference.com/w/cpp/language/explicit

A*******e
发帖数: 2419
6
引入operator other()的目的是有时候other类是使用者无法修改的
比如是一些闭源的代码
这时候other2类中加入operator other()的自定义转换函数就能使得
从other可以转换到other2 other2也能转换到other
作为一种"对称". (我参考的原帖下面reference中解释)
说实话,这种用法真的很古怪。

【在 r*g 的大作中提到】
: 标准中说引入explicit是为了抑制意料之外的隐士类型转换
: 这个东西来自于C, 在C++中继承了这一特性
: 但是就挖出了这么多坑
: 最开始explict Constructor(other)
: 是为了抑制其他other2 先转换为other再调用
: Constructor(other)
: 引入operator other()的目的是有时候other类是使用者无法修改的
: 比如是一些闭源的代码
: 这时候other2类中加入operator other()的自定义转换函数就能使得
: 从other可以转换到other2 other2也能转换到other

1 (共1页)
进入Programming版参与讨论
相关主题
Bjarne Stroustrup C++第四版电子版出来了Is the order of initialization a, b, c or c, b, a?
有人看了新版 1368页的 c++ programming language 吗The untold truth about C++
C++必备书籍推荐How to initialize object in constructor?
重新捡起C++怎么上手?C++,大家觉得最值得买最想买最不后悔买的书是哪本?
请教问题VB, C++初学者清推荐书籍
一个 default constructor 的问题哪位大侠有如下书籍的电子版,或者下载地址,多谢
C++ 中 myobject * a =new myobject[n] 的问题C++0x
[合集] 一些C++问题读Bjarne Stroustrup写得The C++ programming language 是不是经常有不知所谓的感觉。
相关话题的讨论汇总
话题: c++话题: operator话题: init话题: explicit