【问题标题】:Sequential Type Casting of User Defined Type in C++C++中用户定义类型的顺序类型转换
【发布时间】:2012-01-07 02:38:06
【问题描述】:

此代码使用公共隐式 bool 转换(在下面注释掉,http://ideone.com/FDJHB)或通过公共隐式 int 转换后跟隐式 int 到 bool 转换(如下所示,http://ideone.com/kHQ46)编译和运行。但是,将 bool 强制转换设为私有(在下面注释掉,http://ideone.com/4poze)会导致编译错误。为什么在这种情况下通过 int 的路由不再是一个选项?像这样的顺序转换是否具有定义的行为?谢谢。

http://ideone.com/kHQ46

#include <iostream>

class MyObject {
 public:
  MyObject(int theInt) : theInt_(theInt) {
    return;
  }

  MyObject& operator=(MyObject& source) {
    std::cout << "assign op" << std::endl;
    theInt_ = source.theInt_;
    return *this;
  }

  friend MyObject operator*(MyObject& lhs, MyObject& rhs);

  operator int() {
    std::cout << "int conv" << std::endl;
    return theInt_;
  }

/*
  operator bool() {
    std::cout << "bool conv" << std::endl;
    return theInt_;
  }
*/

 private:

  int theInt_;

  MyObject(MyObject& source);
//  operator bool();

};

MyObject operator*(MyObject& lhs, MyObject& rhs) {
  std::cout << "mult op" << std::endl;
  return MyObject(lhs.theInt_*rhs.theInt_);
}


int main(int argc, char* argv[]) {

  MyObject a(1);
  MyObject b(2);
  MyObject c(3);

  if (a * b = c) std::cout << "Oh-no!" << std::endl;

  return 0;
}

编辑:根据要求,相关的编译器消息。

1) 给定代码的输出,将 int 转换为 bool:

多重运算

int 转换

分配操作

int 转换

哦不!

2) 带有公共 bool 类型转换的代码的输出:

多重运算

int 转换

分配操作

布尔转换

哦不!

3) 如果 bool cast 设为私有,则编译器错误:

prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:34: error: ‘MyObject::operator bool()’ is private
prog.cpp:50: error: within this context

【问题讨论】:

  • 你是说当你取消注释operator bool的公共定义时,代码仍然可以编译,但是当你也取消注释私有声明时,它就无法编译?
  • 另外,请编辑您的问题以包含您收到的实际编译器错误消息。
  • Oli:我添加了一些链接来解决这个问题。案例 1 是未注释的公共 bool 类型转换,没有其他任何更改。案例 2 完全一样。案例 3 是未注释的私人演员,没有其他任何变化。
  • chrisaycock:那部分是我所期待的,我并不感到惊讶。但是我不明白为什么如果对象的 bool 转换是私有的,那么转换不能去 int 到 bool。
  • @Praxeolitic 我在看到您的更新之前添加了该评论。请忽略。

标签: c++ casting


【解决方案1】:

为了将您的类型转换为bool,编译器会根据一组(相当复杂的)规则选择“最佳”转换路径。

如果定义了operator bool(),那么它提供了比operator int()更好的转换,然后是从intbool的转换;转化次数较少的路径被视为“更好”。

此过程中不考虑可访问性,因此即使它是私有的,它也会选择operator bool()。那么编译就会失败,因为operator bool()是私有的。

【讨论】:

  • 这组规则是标准的一部分还是编译器的一部分?
  • @Praxeolitic:它们是由标准定义的(在 C++11 第 4 部分和第 12.3 部分中,如果您想了解血淋淋的细节)。
【解决方案2】:

简而言之,编译器选择首先调用哪个方法,然后检查是否允许执行它。当它可以看到operator bool 时,这就是if 检查的最佳匹配,所以它会选择那个,然后发现它是私有的并且不能使用。

还要注意(a * b = c)c 分配给从乘法返回的临时值,然后评估它是零还是非零。我想不出这样的东西会有用的场景。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多