当前位置: 首页 > 知识库问答 >
问题:

为什么C++隐式转换有效,而显式转换不行?

陈朗
2023-03-14

以下代码在C++11中编译成功:

#include "json.hpp"
using json = nlohmann::json ;

using namespace std ;

int main(){
    json js = "asd" ;
    string s1 = js ; // <---- compiles fine
    //string s2 = (string)js ; // <---- does not compile
}

它包括用于现代C++的JSON。一个工作示例在这个Wandbox中。

JSON变量js被隐式转换为字符串。但是,如果我取消最后一行的注释,这是一个显式转换,它将无法编译。这里的编译结果。

除了这个json库的特殊细微差别之外,如何编写一个类,使隐式转换工作,而显式转换不工作?
是否有某种构造函数限定符允许这种行为?

共有1个答案

颛孙英才
2023-03-14

下面是一个简化的代码,它再现了同样的问题:

struct S
{
    template <typename T>
    operator T() // non-explicit operator
    { return T{}; }
};

struct R
{
    R() = default;
    R(const R&) = default;
    R(R&&) = default;
    R(int) {} // problematic!
};

int main()
{
    S s{};
    R r = static_cast<R>(s); // error
}

我们可以看到编译错误类似:

error: call of overloaded 'R(S&)' is ambiguous
     R r = static_cast<R>(s);
                           ^
note: candidates...
     R(int) {}
     R(R&&) = default;
     R(const R&) = default;

这个问题依赖于泛型的s::operator T(),它很乐意将值返回为您想要的任何类型。例如,将s分配给任何类型都将起作用:

int i = s; // S::operator T() returns int{};
std::string str = s; // S::operator T() returns std::string{};
R r(s); // same ambiguity error
R() = default;
R(const R&) = default;
R(R&&) = default;
R(int) {}

A是转换结果所需的类型。P是转换函数模板的返回类型

在这种情况下:

R r = s;

R是转换(A)结果所需的类型。但是,您能否在下面的代码中判断A将表示哪种类型?

R r(s);
 类似资料:
  • 所以,问题是--为什么在I=L的情况下,当L的大小足够小到适合I时,必须显式地进行,但在F=L的情况下,当L的大小也适合F时,铸造可以隐式地进行,而不会产生错误。 我的意思是,在这两种情况下,右操作数的大小可能不适合左操作数。那么,为什么在一种情况下(I=L),强制转换必须显式进行,而在另一种情况下(F=L)可以隐式进行呢?虽然隐式地将长var转换为int var比隐式地将长var转换为浮点var

  • 我试图理解以下转换的机制 根据整数常量,的类型是。这可以通过执行轻松检查; 根据内隐转换语义学: “整数提升是对秩小于或等于int[…]秩的任何整数类型的值的隐式转换设置为int或unsigned int类型的值。“ 如下文所述 msgstr"所有有符号整数类型的行列等于相应无符号整数类型的行列" 因此,升级适用,因为的秩与的秩相同。 这种晋升被定义为 如果int可以表示原始类型的整个值范围(或原

  • 问题内容: “隐式转换”和“显式转换”有什么区别?Java和C ++的区别是否不同? 问题答案: 显式转换是您使用某种语法 告诉 程序进行转换的地方。例如(在Java中): 隐式转换是在没有任何语法的情况下进行转换的地方。例如(在Java中): 应该注意的是(在Java中)涉及原始类型的转换通常涉及某种表示形式的更改,并且可能导致精度降低或信息丢失。相比之下,仅涉及引用类型的转换不会更改基本表示形

  • 问题内容: 您可以将int隐式转换为double: 您可以将int显式转换为double: 您可以将double显式转换为int: 为什么不能将一个double隐式转换为int? : 问题答案: 的范围比宽。这就是为什么您需要显式强制转换。由于相同的原因,您不能隐式地从转换为:

  • 我有一个结构,下面的运算符声明: 仅此运算符就可以将不可为null的结构隐式转换为int,但尝试隐式转换其可为null的对应结构仍会引发编译错误: 无法隐式转换类型

  • 本文向大家介绍C#显式类型转换,包括了C#显式类型转换的使用技巧和注意事项,需要的朋友参考一下 示例