2014-12-18 2 views
-5

Сначала вы должны увидеть ниже код -C++ конструктор «неоднозначным», - но на самом деле это не

#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 ; 
} 

Здесь вы можете увидеть I Я использую два типа конструктора по умолчанию с разными инициализаторами, но когда я пытаюсь скомпилировать, компилятор говорит, что аргументы конструктора являются «неоднозначными». Более того, в конце сообщения компилятора сказано что-то о 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&&) 
+1

Почему вы думаете, что они не двусмысленны? –

+0

'Я использую два типа конструктора по умолчанию с различным инициализатором', и там проблема. – PaulMcKenzie

+0

сторона примечание: 'return 1;' -> 'return 0;' или не помещать 'return' в main вообще –

ответ

1

Первая перегрузка принимает аргумент 0-1; второй принимает 0-2 аргументов. Таким образом, при вызове с 0 или 1 аргументами оба одинаково хороши. Поэтому это неоднозначно.

Тот факт, что, как вы говорите, это «два типа конструктора по умолчанию», в значительной степени гарантирует, что они неоднозначны. Если вы создаете два стандартных конструктора, как компилятор может узнать, какой из них использовать?

1

Компилятор имеет полное право дать вам ошибку, потому что это test(int data1 = 1, int data2 = 2) означает, что если есть нет другой функции перегрузки, как test(int data1 = 1) тогда я должен еще быть в состоянии назвать test(int data1 = 1, int data2 = 2) как этот

test(2); 

Так что, безусловно, неоднозначны. То, с чем вы сталкиваетесь, - most vexing parse. «Самый неприятный синтаксический разбор» - это термин, придуманный Скоттом Мейерсом для двусмысленности в синтаксисе объявления C++, который ведет к противоречивому поведению.

1

Is является неоднозначным: Вы можете позвонить

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.
-> Что должен компилятор делать с 0 или 1?

0

если вы вызываете test(), какой из двух конструкторов будет называться ??проблема заключается в том, что аргументы cunstructors имеют значение по умолчанию, если вы удаляете значение по умолчанию, я уверен, что он будет работать, потому что вы должны указать входные аргументы, которые однозначно определяют правильный конструктор.

0

В этом определении объекта t1

test t1(1) ; 

может быть вызван либо первый конструктор объявлен как

test(int data1 = 1); 

с аргументом 1 или второй конструктор объявлен как

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

с первым аргументом, равным 1, и вторым аргументом, который является аргументом по умолчанию.

Чтобы избежать двусмысленностей вы можете объявить второй конструктор как

test(int data1, int data2); 

Примите во внимание, что существует противоречие между вашими оригинальными конструкторами. Если используется первый конструктор, тогда данные данных данных2 имеют значение по умолчанию -1, а если используется второй конструктор, то значением по умолчанию данных данных данных является значение 2. Это плохой дизайн, поскольку он может путать пользователей. L)

Смежные вопросы