【问题标题】:Why doesn't the `explicit` keyword prevent a `char` from being converted into an `int`?为什么 `explicit` 关键字不能阻止 `char` 转换为 `int`?
【发布时间】:2020-08-09 11:14:32
【问题描述】:

据我了解,在以下代码中,explicit A(int a) 应该阻止 A b('g'); 使用 int 构造函数:

#include <iostream>

class A
{
    public:
        int x;
        char *y;

        A() : x(0) {}
        explicit A(int a) : x(a) { std::cout<<"INT\n"; }
        A(char *b) : y(b) { std::cout<<"C STRING\n"; }
};

int main()
{
    A a(5); /// output: "INT"
    A b('g'); /// output: "INT"
    A c("Hello"); /// output: "C STRING"
}

但是,A b('g'); 使用 int 构造函数...为什么?

另外,另一个问题:如果我写 A(const char *b) 而不是 A(char *b),它会给我以下错误:invalid conversion from 'const char*' to 'char*' [-fpermissive]。为什么我不能将 const char* 转换为 char*

【问题讨论】:

  • 因为这是标准所要求的。给定A b('g'),编译器会查找一个构造函数调用,该调用只涉及char(即'g')的一次隐式转换。它找不到接受char(通过值或const 引用)的构造函数,但确实找到了接受int 的构造函数。单个隐式转换可用于将char 转换为int,因此编译器将'g' 转换为int,然后调用接受int 的构造函数。
  • 是的,但是 explicit 关键字不应该通过不允许 any 隐式转换来避免这种情况吗?
  • @H-005 不,它只影响标记为explicit的用户自定义转换函数,如您的代码中的A::A(int)。它不会影响像charint 这样的标准转换。
  • explicit 关键字意味着A x = 2A y = 'g' 将失败,但A x(2)A y('g') 不会。它与隐式转换无关(例如将'g'char 转换为int)会影响调用哪个构造函数的选择。

标签: c++ constructor implicit-conversion c-strings explicit


【解决方案1】:

explicit 关键字可防止从 intA 的隐式转换。但不影响直接调用A构造函数时charint转换的可能性。

换句话说,explicit 仅影响到您的类A 的转换,但不会影响构造函数参数的任何可能转换。

【讨论】:

    【解决方案2】:

    您正在使用direct initialization,它确实考虑了explicit 构造函数。

    直接初始化比复制初始化更宽松:复制初始化只考虑非explicit构造函数和非显式用户定义conversion functions,而直接初始化考虑所有构造函数和所有用户定义的转换函数.

    给定A b('g');'g' 是一个char,可以隐式转换为int,然后调用A::A(int) 来初始化对象。

    另一方面,copy initializationA a = 5;A b = 'g'; 将不起作用。

    此外,复制初始化中的隐式转换必须直接从初始化器生成 T,而例如直接初始化需要从初始化程序隐式转换为 T 的构造函数的参数。

    关于

    为什么我不能将 const char* 转换为 char*

    const char* 无法隐式转换为 char*。您可以使用const_cast,但请注意它很危险,例如尝试修改字符串文字会导致未定义的行为。

    【讨论】:

      猜你喜欢
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-05
      • 2023-01-06
      • 1970-01-01
      • 2013-09-22
      • 2012-10-17
      相关资源
      最近更新 更多