Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R5.1.11 并未完全展示出“怪异”的点,且并未描述清楚其转换构造函数的过程,可以改进 #55

Open
Mq-b opened this issue Jun 25, 2024 · 1 comment

Comments

@Mq-b
Copy link
Contributor

Mq-b commented Jun 25, 2024

safe-rules/c-cpp-rules.md

Lines 5943 to 5957 in 60fec0a

示例:
```
class String {
public:
String(int capacity); // Non-compliant, missing ‘explicit’
....
};
void foo(const String&);
int bar() {
foo(100); // Can be compiled, but very odd
}
```
由于 String 类的构造函数接受一个 int 型参数,foo(100) 相当于将 100 隐式转为 String 类的对象,这种隐式转换是怪异的,也往往意味着意料之外的错误。

foo(100) 相当于将 100 隐式转为 String 类的对象,这种隐式转换是怪异的,也往往意味着意料之外的错误

这是不对的,事实上我认为也展示不出所谓的怪异,准确的说是 100 用于调用转换构造函数,构造出一个临时的 String 对象,再用来初始化函数 foo 的形参,大约类似于 foo(String(100)) 。如果还未达到 C++17,没有强制的复制消除,则还需要重载决议选择,走一个移动构造或者复制构造。也就是总归有两次构造。

简单来说

#include <type_traits>

class String {
public:
    String(int capacity) {};
    String(const String&) = delete;
};

void f(String){}

int main(){
    f(100);
    String s = 100;
}

https://godbolt.org/z/bMdoYfrzn

这段代码在 C++17 之前无法通过编译,因为我显式定义的弃置的复制构造函数抑制了移动的生成,重载决议选择到了复制构造,但是因为复制构造是弃置的,所以编译错误。C++17 复制消除,无重载决议。

本条规则本身并无问题,但是描述略显不够清楚和怪异,其实直接拿 = 复制初始化会更加直接。

也可以直接点说,C++17 之前,如果不使用 explicit 修饰单个参数的构造函数,从而用户得以使用复制初始化,还可能导致额外的开销。

这也明显存在更多的问题,这个也可以参见 loser homework 稍微提到的。

总而言之,我认为真正应该强调的怪异应该是其多次的构造乃至可能产生的开销

@Mq-b Mq-b changed the title R5.1.11 并未完全展示出“怪异”的点,且并未描述清楚其转换构造函数的过程,可以改进 R5.1.11 并未完全展示出“怪异”的点,且并未描述清楚其转换构造函数的过程,可以改进 Jun 25, 2024
@frederick-vs-ja
Copy link

我想这里的怪异应该是:X 能隐式转换成 Y 时,那么所有(传值或能绑定到右值的引用)接受 Y 的函数都应该同样接受 X 并进行同样的隐式转换吗?如果函数接受的是某种视图类型,那么隐式转换似乎是合理的,但其他类型可能就不一定了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants