【问题标题】:Should I declare conversion operators explicit in C++11?我应该在 C++11 中显式声明转换运算符吗?
【发布时间】:2016-03-29 16:46:14
【问题描述】:

在C++11中,推荐:

  1. 明确定义我们自己的复制/移动构造函数,这样编译器就不会自己做(根据 [1])。
  2. 将单参数构造函数显式声明为显式,以避免隐式转换(根据 [2])。

是否应该在这种思路中声明转换运算符explicit 以防止编译器使用它们来执行隐式转换?

【问题讨论】:

  • "明确定义我们自己的复制/移动构造函数" 嗯,不。你是从哪里听来的?还是您将= default 视为定义?
  • 建议#1 来自哪里?在大多数情况下,编译器生成的复制和移动构造函数都可以。只是需要手动管理资源(例如内存)的类需要自己定义。
  • 我完全不同意第 1 点。除非您正在编写资源管理类,否则请遵循 Rule Of Zero
  • 这取决于您是否要允许隐式转换。 (如果不是,您可以考虑使用命名函数而不是显式转换运算符)。
  • 我认为这将是一个很好的问题,如果它只是询问“何时显式声明转换运算符”。

标签: c++ c++11 type-conversion implicit-conversion


【解决方案1】:

在C++11中,推荐:

  1. 明确定义我们自己的复制/移动构造函数,这样编译器就不会自己做。

无论谁提出该建议,都是错误的。只要默认实现满足您的需求,就使用它。你自己可能不会变得更好。

  1. 将单参数构造函数显式声明为显式,以避免隐式转换。

C++ Core Guidelines 表示“默认情况下,声明单参数构造函数 explicit”。在某些情况下,您可能更喜欢隐式构造(例如,std::string 来自 const char*)。在这些情况下,请忽略 explicit 声明。

在这种思路中,是否应该显式声明转换运算符以防止编译器使用它们来执行隐式转换?

将它们明确化并没有什么好处。这意味着,转换只能与强制转换一起使用。强制转换比 getter 函数调用更难阅读。写转换运算符,当你想隐式转换时,当你想显式转换时写getter。

【讨论】:

    【解决方案2】:

    答案是“不,你不应该”。显式转换运算符被添加到语言中以处理下面描述的特定问题。当您不处理该特定问题时,您应该向目标类添加显式复制构造函数,或者编写命名函数而不是转换运算符(如c_str() 中的std::string)。

    让我们退后一步,从总体上考虑转换。当您需要编写从 AB 的转换代码时,您有两个选择 - 您可以定义一个单参数构造函数,像这样

    struct B {
        B(const A& a);
    };
    

    或者你可以定义一个转换操作符,像这样:

    struct A {
        operator B() const;
    };
    

    第一种方法在 C++11 之前允许显式/隐式控制。但是,它在以下两种情况下不可用:

    • 您拥有类型 A,但您不拥有类型 B,或者
    • 您拥有类型 A,但类型 B 原始

    根据 C++11 的显式转换运算符的draft paper,委员会在争论向语言中添加显式转换运算符时正在解决这两种情况。 (1) 隐式和隐式复制构造函数、(2) 隐式转换运算符和 (3) 命名成员函数已经涵盖了所有其他情况。

    【讨论】:

      猜你喜欢
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 2014-02-04
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多