23 c++
关于我最近回答的一些评论,在C++中可以使用的其他有用的演员表明,我对C++转换的理解是错误的.只是为了澄清问题,请考虑以下代码:
#include <string>
struct A {
A( const std::string & s ) {}
};
void func( const A & a ) {
}
int main() {
func( "one" ); // error
func( A("two") ); // ok
func( std::string("three") ); // ok
}
Run Code Online (Sandbox Code Playgroud)
我的断言是第一个函数调用是一个错误,因为没有从const char*到A的转换.有一个从字符串到A的转换,但是使用它会涉及多个转换.我的理解是这是不允许的,这似乎是由g ++ 4.4.0和Comeau编译器证实的.使用Comeau,我收到以下错误:
"ComeauTest.c", line 11: error: no suitable constructor exists
to convert from "const char [4]" to "A"
func( "one" ); // error
Run Code Online (Sandbox Code Playgroud)
如果您可以指出我错在哪里,无论是在这里还是在原始答案中,最好是参考C++标准,请这样做.
而C++标准的答案似乎是:
最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值.
感谢Abhay提供报价.
Abh*_*hay 12
我认为尖锐的答案是准确的.标题为"转换"的C++标准(SC22-N-4411.pdf)第12.3.4节明确指出,只允许一个隐式的用户定义转换.
1类对象的类型转换可以由构造函数和转换函数指定.这些转换称为用户定义的转换,用于隐式类型转换(第4节),初始化(8.5)和显式类型转换(5.4,5.2.9).
2用户定义的转换仅在明确无误的情况下应用(10.2,12.3.2).转换遵守访问控制规则(第11条).模糊度解决(3.4)后应用访问控制.
3 [注意:有关在函数调用中使用转换的讨论以及下面的示例,请参见13.3. - 尾注]
4最多只有一个用户定义的转换(构造函数或转换函数)隐式应用于单个值.
似乎已经达成共识:是的,你是对的.
但是由于这个问题/答案可能会成为C++隐式转换在stackoverflow上的参考点,我想补充一点,对于模板参数,规则是不同的.
对于用于模板参数推断的参数,不允许隐式转换.这可能看起来很明显,但仍然会导致微妙的怪异.
例如,std :: string加法运算符
std::string s;
s += 67; // (1)
s = s + 67; // (2)
Run Code Online (Sandbox Code Playgroud)
(1)编译和工作正常,operator+=
是一个成员函数,模板字符参数已经通过实例化为std::string
s(to char
)推导出来.因此允许隐式转换(int
- > char
),导致s包含等效于67的char,例如在ASCII中这将成为'C'
(2)给出的编译器错误operator+
被声明为免费功能,这里的模板字符参数是在扣除使用.