【问题标题】:Why is only one implicit conversion allowed to resolve the parameters to a function in C++?为什么只允许一个隐式转换将参数解析为 C++ 中的函数?
【发布时间】:2010-06-25 20:47:36
【问题描述】:

这行得通:

#include<cstdio>

class A{
public:
    A(int a):var(a){}
    int var;
};

int f(A obj) {
    return obj.var;
}

int main() {
    std::cout<<f(23);  // output: 23
    return 0;
}

虽然不是这样:

#include<cstdio>

class A{
public:
    A(int a, int b):var1(a), var2(b){}
    int var1, var2;
};

int f(A obj) {
    return (obj.var1 + obj.var2);
}

int main() {

    cout<<f(22, 23); // error: conversion from 'int' to 
                     // non-scalar type 'A' requested
    return 0;
}

第二段代码不起作用,但我找不到一个足够好的理由为什么它不起作用。对我来说,代码看起来太奇怪了,无法运行。

但是在这种情况下只允许进行一次隐式转换的真正原因是什么?是不是 this-is-like-this-only 语言功能?

【问题讨论】:

  • 当 f() 的原型只有一个时,为什么要向 f() 传递两个参数?
  • 隐式转换已经够糟糕了。为什么哦,为什么要以指数方式增加其复杂性?
  • @user168715:我不想增加复杂性。我什至希望第一个代码片段失败。我只是想了解为什么有些事情是这样的。

标签: c++ constructor language-features language-design


【解决方案1】:

直接的答案是 C++ 语法在任何情况下都不会将函数参数组合成聚合。在任何情况下,对f(a, b) 的调用都不会被视为对f(c) 的调用,其中c 是由ab 的某种组合构造的值。这不是语言的工作方式。出于重载、隐式转换和所有其他目的,每个参数总是被单独处理。

至于理由,如果允许您提出的问题,您希望如何解决这种情况:

class A {
  public:
    A(int a) : v1(a) {}
  private:
    int v1;
};

class B {
  public:
    B(int a, int b) : v1(a), v2(b) {}
  private:
    int v1;
    int v2;
};

class C {
  public:
    C(int a, int b, int c) : v1(a), v2(b), v3(c) {}
  private:
    int v1;
    int v2;
    int v3;
};

void f(A obj1, A obj2) { /* ... */ }

void f(B obj) { /* ... */ }

void g(A obj1, B obj2) { /* ... */ }

void g(B obj1, int i) { /* ... */ }

void g(C obj) { /* ... */ }

int main() {
   f(22, 23); // Call f(A,A) or f(B)? 
   g(22, 23, 24); // Call g(A,B) or g(B, int), or g(C)? 
   return 0;
}

【讨论】:

  • 谢谢!据我说,即使f(23)(在我的第一个代码片段中)也应该失败。即使这样也很丑。
  • 您可以通过在A 构造函数上使用explicit 关键字来使f(23) 失败,即explicit A(int) : var(a) {}explicit 关键字意味着构造函数必须始终显式使用,并且不能用于隐式转换。显然,这只对只接受一个参数的构造函数有意义。
【解决方案2】:

您正在查看第二个示例,就像 (22, 23) 一样,其中一个元组(即一个对的单个变量)不是。函数 f 只接受一个变量。当您尝试向它传递两个将失败的变量时。

第一个有效的原因是编译器可以从 int 转换为 A。但是您不能将两个变量转换为单个变量,C++ 不允许这样做。

【讨论】:

    【解决方案3】:

    只有可以用一个参数调用的构造函数才定义隐式转换,因此在第二个示例中不可能进行隐式转换,因为A 的构造函数没有一个参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 2010-12-29
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 2022-10-04
      相关资源
      最近更新 更多