代码之家  ›  专栏  ›  技术社区  ›  anon

C++隐式转换

c++
  •  23
  • anon  · 技术社区  · 15 年前

    对我最近的回答有几条评论, What other useful casts can be used in 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
    }
    

    我的断言是,第一个函数调用是一个错误,因为没有从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
    

    如果你可以指出,我错了,无论是在这里还是在原来的答案,最好是参照C++标准,请这样做。

    而C++的答案似乎是:

    最多一个用户定义的转换 (构造函数或转换函数) 隐式应用于单个值。

    感谢Abhay提供的报价。

    4 回复  |  直到 8 年前
        1
  •  12
  •   Abhay    15 年前

    我认为夏普图斯的回答是准确的。C++标准(SC22-N-1111.pdf)第123.4节标题“转换”清楚地表明,只允许一个隐式用户定义的转换。

    1类对象的类型转换可以由 构造器和通过转换 功能。这些 转换称为用户定义的转换,并使用 对于隐式类型转换(子句 4) 初始化(8.5),对于显式类型转换(5.4, 5.2.9)。

    2用户定义的转换仅应用于 明确(10.2,12.3.2)。 转换遵守 访问控制规则(第11条)。访问控制在 模糊度解决(3.4)。

    3[注:关于转换使用的讨论,见13.3 在函数调用和示例中 下面。阿末 注释

    4最多一个用户定义的转换(构造函数或转换) 函数)隐式应用于 单一的 价值。

        2
  •  9
  •   Pieter    15 年前

    正如人们已经达成的共识:是的,你是对的。

    但是,由于这个问题/答案很可能成为StCube上C++隐式转换的参考点,所以我想补充一下,对于模板参数,规则是不同的。

    不允许对用于模板参数推导的参数进行隐式转换。这看起来很明显,但也可能导致微妙的奇怪。

    case-in-point,std::string加法运算符

     std::string s;
     s += 67;    // (1)
     s = s + 67; // (2)
    

    (一)编译、工作良好; operator+= 是成员函数,模板字符参数已通过实例化推导出来 std::string 为S(to) char )所以允许隐式转换( int -gt; 烧焦 ,结果在s中包含相当于67的字符,例如在ascii中,这将变为“c”

    (2)给出编译器错误 operator+ 声明为自由函数,这里是模板字符参数 用于扣减。

        3
  •  8
  •   sharptooth    15 年前

    没错,只有一个 隐性的 允许转换。

    一行中的两个转换可以使用转换运算符和参数化构造函数的组合执行,但这会导致 C4927 warning -“非法转换;隐式应用了多个用户定义的转换”-在VC++中是有原因的。

        4
  •  6
  •   drhagen    8 年前

    The C++ Programming Language (第四)。爱德华兹) (第18.4.3节)规定

    只有一个用户定义的级别 隐式转换是合法的

    “用户定义的”部分使其听起来像在本地类型之间允许进行多个隐式转换。