【问题标题】:redefinition of a variable with a different type [duplicate]重新定义具有不同类型的变量[重复]
【发布时间】:2020-03-06 23:41:14
【问题描述】:

抱歉问题标题,但我不知道我的问题的正确标题。我有以下代码示例:

struct test {
    test(int a) {
    }
};

int main() {
    test(1);
    return 0;
 }

上面的示例代码有效。现在我(以我的理解)做同样的事情有点不同:

struct test {
     test(int a) {
     }
};

int main() {
    int a = 0;
    test(a);
    return 0;
}

编译时出现以下错误:

error: redefinition of 'a' with a different type: 'test' vs 'int'

但在我看来,当我尝试这个时,它会变得非常奇怪:

struct test {
    test(int a) {
    }
};

int main() {
    int a = 0;
    test((int)a);
    return 0;
}

上面的例子再次起作用,真的让我很困惑,因为我看不出有什么区别(除了将 int 转换为 int)。谁能解释发生了什么?提前谢谢你。

【问题讨论】:

  • 这被称为最麻烦的解析。 Clang 是 more helpful 而不是 GCC:warning: parentheses were disambiguated as redundant parentheses around declaration of variable named 'a' note: add enclosing parentheses to perform a function-style cast

标签: c++


【解决方案1】:

在 C++ 中定义变量的语法有点古怪...

当你这样做时

test(1);

您创建了一个test 结构的临时对象。该对象将立即销毁。

但是当你这样做时

test(a);

您没有创建一个临时的test 对象,您实际上定义了一个名为a 的变量。相当于

test a;

你可以用花括号解决这个问题

test{a};

或者通过对“参数”使用显式表达式(就像您对演员所做的那样),因此不能用作变量名。在您需要消除变量和表达式之间的歧义的类似情况下,通常使用一元 +,如

test(+a);

【讨论】:

    【解决方案2】:

    这真的很棘手:

    test(1);
    

    这是带有参数 1 的 test 的构造。

    int a = 1;
    test(a);
    

    编译器将其读取为test a;test 的实例名为a - 具有默认构造)。 test 甚至没有提供默认构造函数,此时编译器不会考虑。

    修复(由 OP 发现):

    int a = 1;
    test((int)a);
    

    现在,编译器被明确告知将a 读取为表达式(但不是标识符)。

    【讨论】:

      【解决方案3】:

      您忘记为您的test 变量命名,导致test(a); 成为test 类型的名为a 的变量的声明。

      在其他情况下,由于test(1)test((int)a) 不能是声明,而必须是某种调用,您的编译器会将其视为构造一个没有名称的test 类型的临时对象。

      【讨论】:

        【解决方案4】:

        ISO C++ 标准 (ISO/IEC 14882) 20033.2 部分:

        在任何翻译单元中,模板、类型、函数或对象都只能有一个定义

        请注意,单一定义规则 (ODR) 是 C++ 编程语言中的一个重要概念。

        如果您想拥有许多同名的函数(当然还有不同的签名),function overloading 是您想要的功能。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多