在下面的示例中,为什么我只能将protected $except = [
"project_save"
];
传递给string
?
printFoo()
无论出于何种原因,我都在脑海中自动确定并使用构造函数来构造对象。
为什么我不能这样做,但我可以将#include <string>
#include <iostream>
using namespace std;
class Foo {
public:
Foo(const Foo &foo) : str(foo.str) {}
Foo(string str) : str(str) {}
string str;
};
void printFoo(Foo foo) {
cout << foo.str << endl;
}
int main() {
Foo foo("qux");
printFoo(foo); // OK
printFoo("qix"); // error: no matching function for call to 'printFoo'
return 0;
}
常量传递给接受char[n]
的参数,例如?
答案 0 :(得分:14)
将涉及两个隐式转换:
std::string
Foo
C ++最多只能做一次:
来自4次标准转换(N3337)
标准转化是具有内置含义的隐式转化。 第4条列举了全套此类转换。一个标准 转换序列是一系列标准转换 以下顺序:
- 来自以下集合的零次或一次转换: 左值到右值的转换,数组到指针的转换,以及 函数到指针的转换。
- 来自的零或一次转换 以下集:积分促销,浮点促销,积分 转换,浮点转换,浮点积分 转换,指针转换,指向成员转换的指针,以及 布尔转换。
- 零或一个资格转换。
12.3转换(N3337)
1类对象的类型转换可以由构造函数指定 通过转换功能。这些转换称为用户定义 转换并用于隐式类型转换(第4条),for 初始化(8.5),以及显式类型转换(5.4,5.2.9)。
2用户定义的转换仅在明确无误的情况下应用 (10.2,12.3.2)。转换遵守访问控制规则(第11条)。 模糊度解决(3.4)后应用访问控制。
[...]
4 最多一个用户定义的 隐式应用转换(构造函数或转换函数) 为单个值。
(强调我的)
答案 1 :(得分:7)
根据C ++标准§12.3/ 4转换[class.conv]:
最多一个用户定义的转换(构造函数或转换 function)隐式应用于单个值。
因此,不允许编译器连续应用两次转换。也就是说,首先是从const char[4]
到std::string
,其次是从std::string
到Foo
。
为此,您需要定义一个额外的构造函数:
Foo(char const *str_) : str(str_) {}
答案 2 :(得分:5)
这是因为允许编译器考虑一次转换。
要做你需要做的事情,编译器需要进行两次转换。
printFoo("qix");
// Actually needs.
printFoo(Foo(std::string("qix")));
如果你改变它,那么你传递一个字符串就可以了。
printFoo(std::string("qix"));
所有这些背后的主要原因是字符串文字的类型为char const[<size>]
NOT std::string
答案 3 :(得分:1)