Можем ли мы перегрузить конструктор, основываясь на типе ссылочного параметра?

Я знаю, что мы не можем перегружать конструкторы, как показано ниже (Единственное отличие заключается в списке инициализации):

myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){

cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}

myClass(const INT& oInt,const STRING& oStr){
I=oInt;
STR=oStr;
cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}

Но предположим, что я хочу перегрузить свой конструктор так:

myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr);
myClass(const INT oInt,const STRING oStr);

то есть на основе другого типа параметра one as reference type другой as normal type

Я имею в виду мой старый вопрос:
Перегрузка функции-члена класса

Это может быть достигнуто?

Мой код:

#include <iostream>
#include <string>

using namespace std;

class INT{
int i;
public:

INT(int i=0):i(i){
cout << "INT Class Object Created with i : " << i << endl;
}

~INT()
{
cout << "INT Class Object Destructed with i :" << i << endl;
}

INT(const INT& I){
i=I.i;
cout << "INT Class Copy Constructor called for i : "<< i << endl;
}

INT& operator= (const INT& I){

i=I.i;
cout << "INT Assignment operator called for i : "<< i << endl;
return *this;
}

friend ostream& operator << (ostream& os,const INT& I){
os << I.i ;
return os;
}

};class STRING{

string str;

public:
STRING(string str=""):str(str){

cout << "STRING Class Object Created with str : " << str << endl;
}
~STRING()
{
cout << "STRING Class Object Destructed with str :" << str << endl;
}STRING(const STRING& S){
str=S.str;
cout << "STRING Class Copy Constructor called for str : "<< str << endl;
}

STRING& operator= (const STRING& S){

str=S.str;
cout << "STRING Assignment operator called for str : "<< str << endl;
return *this;
}

friend ostream& operator << (ostream& os,const STRING& S){
os << S.str ;
return os;
}

};class myClass{

INT I;
STRING STR;
public:

myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){

cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}

myClass(const INT oInt,const STRING oStr){
I=oInt;
STR=oStr;
cout << "my Class Object Created with I : " << I << " STR : " << STR << endl;
}~myClass()
{

cout << "my Class Object Destructed with I : " << I << " STR : " << STR << endl;

}

};
int main()
{

INT iObj(5);
STRING strObj("Alina Peterson");cout << "\n\n======================================================\n\n" << endl;

myClass myObj(iObj,strObj);

cout << "\n\n======================================================\n\n" << endl;

return 0;
}

Я получаю ошибку:

$ g++ -g -Wall CPP.cpp -o CPP
CPP.cpp: In function ‘int main()’:
CPP.cpp:116:32: error: call of overloaded ‘myClass(INT&, STRING&)’ is ambiguous
myClass myObj(iObj,strObj);
^
CPP.cpp:116:32: note: candidates are:
CPP.cpp:86:1: note: myClass::myClass(INT, STRING)
myClass(const INT oInt,const STRING oStr){
^
CPP.cpp:81:1: note: myClass::myClass(const INT&, const STRING&)
myClass(const INT& oInt,const STRING& oStr):I(oInt),STR(oStr){
^

Как я приведу свой конструктор, чтобы он мог различать две версии моего перегруженного конструктора?

0

Решение

Вы можете перегрузить конструктор на T const& а также T но компилятор не может выбрать конструктор, в результате чего получается пара некалавных конструкторов: ни один из них не лучше другого для любого из жизнеспособных аргументов. Кроме того, вы не можете явно выбрать конструктор: конструкторы не являются обычными функциями, и вы не можете их приводить. Таким образом, перегрузка конструктора на T const& а также T совершенно бесполезно. Тем не менее, вы Можно перегрузка на основе rvalueness: один конструктор должен взять T const& а другой взять T&&,

Может быть, вы должны спросить о какие Вы хотите достичь, а не как вы пытаетесь достичь этого …

2

Другие решения

Скажем, у вас есть две функции:

void foo(int const x) {}
void foo(int const& x) {}

Когда вы звоните

foo(10);

компилятор не может устранить неоднозначность между двумя перегруженными функциями.

Когда у тебя есть:

void foo(int& x) {}
void foo(int const& x) {}

и сделать тот же звонок, foo(10);компилятор правильно выберет второй.

Что у тебя есть

myClass(const INT& oInt,const STRING& oStr);

myClass(const INT oInt,const STRING oStr);

аналог первой пары функций.

Вопрос, который вы должны задать себе, заключается в том, какие требования побуждают вас создавать такие перегрузки. Это реальные требования? Если ваши требования не являются чем-то необычным, вы сможете справиться только с одним из них.

1

хорошо позвонить

myClass(const STRING& oStr, const INT& oInt):I(oInt),STR(oStr) {}

Вы можете сделать одно из следующих

INT iObj(5);
STRING strObj("Alina Peterson");

INT& x = iObj;
myClass myObj(x, strObj);

ИЛИ ЖЕ

myClass myObj(*(&iObj), strObj);

для другого конструктора, я не думаю, что вы можете вызвать его, всегда приведет к ошибке

0

Вы не можете обойти тот факт, что у вас не может быть двух функций (конструкторов или других), которые принимают одинаковые параметры. Если вы делаете это, вы не перегружаетесь, вы просто дублируете функцию. Компилятор не делает специального исключения для передачи по ссылке, а не по значению.

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

-1