c ++构造函数'模糊' - 但事实并非如此

时间:2014-12-18 08:31:57

标签: c++ c++11

首先,您需要查看以下代码 -

#include <iostream>
using std::cout; using std::endl ;

class test
{
    private:
        int data1, data2 ;
    public:
        test(int data1 = 1) { 
            this->data1 = data1 ; this->data2 = -1;
        }
        test(int data1 = 1, int data2 = 2) { 
            this->data1 = data1 ; this->data2 = data2 ; 
        }
};

这是主要的 -

int main()
{
    test t1(1) ;
    test t2(1, 2);
    return 1 ;
}

在这里你可以看到我使用两种类型的默认构造函数和不同的初始化程序,但是当我尝试编译时,编译器会说构造函数参数是“不明确的”。此外,编译器消息的结尾说明了constexpr - 我不知道这是什么。

我错过了什么?

这是编译器错误消息 -

test.cpp: In function ‘int main()’:
test.cpp:19:11: error: call of overloaded ‘test(int)’ is ambiguous
  test t1(1) ;
           ^
test.cpp:19:11: note: candidates are:
test.cpp:12:3: note: test::test(int, int)
   test(int data1 = 1, int data2 = 2) { 
   ^
test.cpp:9:3: note: test::test(int)
   test(int data1 = 1) { 
   ^
test.cpp:4:7: note: constexpr test::test(const test&)
 class test
       ^
test.cpp:4:7: note: constexpr test::test(test&&)

5 个答案:

答案 0 :(得分:1)

编译器完全有权向您提供错误,因为test(int data1 = 1, int data2 = 2)表示如果没有其他函数重载如test(int data1 = 1)那么我应该仍然可以调用test(int data1 = 1, int data2 = 2)喜欢这个

test(2);

所以这绝对是模棱两可的。您面临的是 most vexing parse 。 “最令人烦恼的解析”是Scott Meyers创造的一个术语,指出C ++声明语法含糊不清会导致反直觉行为。

答案 1 :(得分:1)

第一个重载需要0-1个参数;第二个需要0-2个参数。因此,当使用0或1参数调用时,两者都同样好。因此,它含糊不清。

正如你所说,这些是&#34;两种类型的默认构造函数&#34;几乎保证他们是不明确的。如果您创建了两个默认构造函数,编译器如何知道要使用哪个?

答案 2 :(得分:1)

是不明确的:您可以致电

test(int data1 = 1) { 
    this->data1 = data1 ; this->data2 = -1;
}

有0或1个参数,

test(int data1 = 1, int data2 = 2) { 
    this->data1 = data1 ; this->data2 = data2 ; 
}

0,1或2 - &GT;编译器应该用0或1做什么?

答案 3 :(得分:0)

如果调用test(),将调用两个构造函数中的哪一个?问题是cunstructors的参数有一个默认值,如果你删除默认值我很确定它会起作用,因为你必须指定唯一确定正确构造函数的输入参数

答案 4 :(得分:0)

在对象t1

的定义中
test t1(1) ;

可以将第一个构造函数称为

test(int data1 = 1);

使用参数1或第二个构造函数声明为

    test(int data1 = 1, int data2 = 2);

第一个参数等于1,第二个参数是默认参数。

为了避免歧义,你可以声明第二个构造函数,如

    test(int data1, int data2 );

考虑到原始构造函数之间存在矛盾。如果使用第一个构造函数,那么数据成员data2的默认值为-1,而如果使用第二个构造函数,则数据成员data2的默认值为2.这是一个糟糕的设计,因为它可能会使用户感到困惑.L)